예전에 리눅스를 사용했을때, gcd를 이용하여 컴파일한 기억이 있어서 서버는 리눅스를 사용했습니다.
대략적인 과정은 아래와 같습니다.
Django와 Node.js 를 분리하여 사용하였는데 그 이유는 Node.js에 편리한 라이브러리가 많았기 때문입니다.
Django는 사용자가 요청을 하면 응답을 해주는 용도로 사용하였고 Node.js 는 Docker로 사용자들의 환경을 분리하고
Docker환경 내에서 컴파일을 할 수 있도록 설계하였습니다.
이렇게 N명의 유저들을 각각 다른 환경에서 실행할 수 있도록 Docker로 컨테이너를 만들고 그 안에서
컴파일을 수행하였습니다.
더욱 구체적인 동작방식은 이렇습니다. 홈페이지에 접속하면 Django가 인식하여 서버 내부의 Node.js와 socket통신 할 수있는 stream을 만듭니다. 그 때, Docker가 만든 컨테이너의 stream을 socket.io의 스트림 위에 얹어서 socket이 통신하는 길에서 docker 데이터가 전달될 수 있도록 만들었습니다. 그리고 Docker stream을 만든 후, 클라이언트에게 다 만들었다 알려줍니다.
이 과정에서 필요한 Node 모듈은 (Server side)
socket.io
docker.js
입니다.
1. Django (View)
Django는 CodeEditor를 제공하여 편하게 코드를 수정할 수 있도록 도와주고 Terminal을 제공하여 코드를 실행했을 때의 결과를 사용자에게 표시할 수 있도록 도와줍니다. Run버튼을 클릭했을 때에는 CodeEditor에 있는 코드들을 그대로 SSH Server에 전송합니다.
그림 4는 코드 수정페이지의 시작화면입니다. 왼쪽은 Code Editor로 코드를 수정하는 부분입니다.
코드를 모두 작성하고 상단의 Run 버튼을 누르면 결과가 Terminal에 출력됩니다.
Code Editor는 monaco-editor.js 라이브러리를 사용하였습니다. monaco-editor는 js파일과 css파일을 추가하기만 하면 되기 때문에 생략하겠습니다.
1.1 Socket에 EventListener 추가
setSocket함수는 SSH 서버와 연결하기 위한 함수입니다. io.connect로 반환된 socket으로 해당 서버에게 메세지를 주고 받을 수 있는 역할을 담당합니다.
emit을 통해 특정 메시지를 전달할 수 있고 on 을 통해 메시지를 받을 수 있습니다.
아래 코드를 보면 ssh서버로부터 'show'이름의 메시지를 받았을 때에는 terminal에 받은 값 그대로 write를 합니다.
terminal에 write를 하면 아래 그림 5와 같이 터미널에 write 인자값에 있는 문자열을 표시합니다.