Guacamole 및 Django를 사용한 웹 기반 원격 데스크톱

아보카도 소스 넣을 까

최근의 일환으로 Rescale hackday에서는 사용자를 대신하여 실행되는 노드에 대해 브라우저 내 원격 데스크톱 기능을 통합하고 싶었습니다. Rescale에 제출된 대부분의 워크플로우는 무인으로 실행되는 일괄 처리 작업이지만, 시스템에 로그인하고 GUI를 실행하여 실행 중인 시뮬레이션을 모니터링하는 기능은 일부 사용자에게 유용할 수 있습니다.
빠른 Google 검색으로 다음과 같은 라이브러리가 나타났습니다. 아보카도 그것은 몇 년 동안 계속되어 왔습니다. Guacamole은 세 가지 주요 구성 요소로 구성됩니다. 다양한 원격 데스크톱 프로토콜(VNC, RDC, SSH) 간을 변환하는 guacd라는 데몬 애플리케이션과 원격 데스크톱을 HTML5 캔버스 요소로 렌더링하고 수신 대기하는 Javascript 라이브러리 세트인 사용자 지정 guacamole 프로토콜입니다. 마우스 및 키보드 이벤트, 그리고 마지막으로 js 라이브러리에서 HTTP 요청을 수신하고 guacd 데몬(*)과 통신하는 얇은 웹 애플리케이션입니다.
안타깝게도 제공된 웹 애플리케이션, Java 서블릿 및 기존 Django 웹 스택 간에 약간의 불일치가 있습니다. 웹 앱의 Python 버전이 있다면 Guacamole을 기존 제품에 통합하는 것이 훨씬 더 간단할 것입니다. 고맙게도, 문서 이 작업은 상대적으로 간단해야 한다고 말합니다. 소스 코드는 잘 작성되었으며 Hackday 품질 버전을 Python으로 빠르게 포팅하는 것은 매우 쉬웠습니다.
과카몰리 js 라이브러리는 웹 앱에 대한 연결 요청을 통해 시작됩니다. 이 시점에서 guacd를 위한 소켓이 열리고 클라이언트에 반환되는 터널 ID가 할당됩니다. 여기서 중요한 점은 이 소켓이 동일한 터널 ID를 포함하는 여러 HTTP 요청에서 공유되어야 한다는 것입니다. 이를 안전하게 수행하기 위해 한 번에 하나의 스레드만 소켓에서 읽거나 소켓에 쓰도록 보장하기 위해 한 쌍의 잠금이 사용됩니다. 다음 코드 조각은 Django 보기 도우미 함수를 통해 guacd 명령이 클라이언트에 반환되는 방법을 보여줍니다.

소켓 = {} 소켓_잠금 = threading.RLock() read_lock = threading.RLock() write_lock = threading.RLock() 보류 중_read_request = threading.Event() def _do_read(요청, 캐시_키): 보류 중_read_request.set() def 콘텐츠(): 소켓_잠금 사용: guac = 소켓[cache_key] 읽기 잠금 사용: 보류 중_read_request.clear() while True: content = guac.read() if content: 콘텐츠 생성 else: break if 보류 중인_read_request.is_set(): logger.info('다른 요청 허용 인계합니다.') break # 명령어 끝 표시는 '0.;'을 생성합니다. response = StreamingHttpResponse( content(), content_type='application/octet-stream') response['Cache-Control'] = 'no-cache' 응답 반환

한 가지 흥미로운 점은 과카몰리 js 라이브러리 AJAX 요청의 교대 쌍을 사용하여 서버에서 데이터를 스트리밍합니다. 먼저 초기 AJAX 요청이 이루어집니다. 이 첫 번째 연결이 열리고 데이터가 서버에서 다시 흐르는 후 어느 시점에 두 번째 연결 시도가 이루어집니다. 웹 앱은 서버 측에서 이를 감지하고 첫 번째 연결을 종료한 다음 두 번째 연결에서 데이터를 다시 보내기 시작할 수 있어야 합니다. Java 코드에서 사용되는 ReentrantLock에는 대기 중인 다른 스레드가 있는지 쉽게 알 수 있는 방법이 있지만 Python RLock은 유사한 메서드를 노출하지 않습니다. 이벤트는 두 개의 진행 중인 HTTP 요청 간의 빠르고 더러운 신호 메커니즘으로 사용되고 있습니다.
분명히 이것은 가능한 한 빨리 해킹되었으며 프로덕션 용도로 적합하지 않으며 아마도 하나 이상의 버그가 포함되어 있을 것입니다. 현재 가장 큰 제한 사항 중 하나는 guacd에 연결된 소켓이 현재 공유된 전역 사전에 저장된다는 것입니다. 따라서 이는 요청을 처리하는 여러 스레드가 있는 단일 프로세스로 실행되는 HTTP 서버에만 적합합니다.
전반적으로, 이식하기에는 재미있는 약간의 코드였습니다. 과카몰리 작가들의 노고에 감사드립니다. 샘플 Django/Guacamole 프로젝트는 다음에서 사용할 수 있습니다. github 궁금하신 분들을 위해.
(*) Guacamole은 웹소켓을 지원하지만 기본적으로 사용하는 HTTP 터널링 접근 방식은 이전 브라우저를 지원하려고 할 때 실제로 이점이 있습니다. 최신 브라우저 동작을 에뮬레이트하는 데 사용할 수 있는 다양한 심에도 불구하고 HTML5 기능에 대한 종속성이 적을수록 레거시 브라우저와의 호환성이 향상됩니다.

비슷한 게시물