예전에 리눅스를 사용했을때, gcd를 이용하여 컴파일한 기억이 있어서 서버는 리눅스를 사용했습니다.
대략적인 과정은 아래와 같습니다.
그림 1
Django와 Node.js 를 분리하여 사용하였는데 그 이유는 Node.js에 편리한 라이브러리가 많았기 때문입니다.
Django는 사용자가 요청을 하면 응답을 해주는 용도로 사용하였고 Node.js 는 Docker로 사용자들의 환경을 분리하고
Docker환경 내에서 컴파일을 할 수 있도록 설계하였습니다.
그림 2
이렇게 N명의 유저들을 각각 다른 환경에서 실행할 수 있도록 Docker로 컨테이너를 만들고 그 안에서
컴파일을 수행하였습니다.
그림 3
더욱 구체적인 동작방식은 이렇습니다. 홈페이지에 접속하면 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
그림 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 인자값에 있는 문자열을 표시합니다.