2012-02-15 6 views
10

나는 파이썬 서버에서 HTML5 캔버스로 이미지를 표시하기 위해 websockify을 사용하고 있습니다.websocket을 통해 이미지 받기

필자는 성공적으로 내 파이썬 서버에서 이미지를 보내지만 내 캔버스에 이미지를 표시 할 수 없다고 생각합니다.

문제는 캔버스에 표시하려고하는 바이트 수와 관련이 있으며 전체 이미지를받은 다음 이미지를 캔버스에 표시 할 때까지 기다리지 않고 있다고 생각합니다.

는 지금까지 내가 가진 :

메시지에 기능. 내가 이미지를 보냈을 때 내가 문자열을 받아 내가 캔버스에 표시하려고 어디 콘솔

ws.on('message', function() { 
    //console.log("MESSAGERECEIVED!") 
      msg(ws.rQshiftStr()); 
    }); 

MSG 기능 12 MESSAGERECEIVED를 얻을. 각 그림마다 12 번씩이 방법을 사용합니다. 이 문제를 해결하는 방법에 대한

function msg(str) { 
     //console.log(str); 
     console.log("RELOAD"); 

     var ctx = cv.getContext('2d'); 
     var img = new Image(); 
     //console.log(str); 
     img.src = "data:image/png;base64," + str; 
     img.onload = function() { 
      ctx.drawImage(img,0,0); 
     } 
    } 

어떤 제안 : 쏘는의 형식은 'xÙõKþ°pãüCY입니까?

+0

클라이언트가 hybi 초안을 지원하지 않으면 이미지를 base64로 웹 소켓을 통해 전송하면 안됩니다. Base64는 33 %의 오버 헤드를 발생시킵니다. 따라서 바이너리로 보내는 것이 바람직합니다. – einaros

+0

'websockify '는 그것을 통해 전달 된 모든 것을 base64로 변환한다고 생각합니다. – glarkou

+0

그럴 경우, 그건 끔찍한 일입니다. 다른 websocket 구현을 찾으십시오. – einaros

답변

11

websockify + websock.js의 핵심은 스트리밍 바이너리 데이터를 투명하게 지원하는 것입니다 (자세한 내용은 아래를 참조하십시오). 수신 큐에서 가져온 데이터는 이미 base64로 디코딩되었습니다. 그러나 데이터 URI 스키마는 base64로 인코딩 된 문자열을 필요로하므로 이미지 데이터를 base64로 인코딩해야합니다. 당신은 base64로 인코딩으로 바이너리 코드 문자열 내장 window.btoa()를 사용할 수 있습니다

img.src = "data:image/png;base64," + window.btoa(str); 

을 또는 더 큰 효율성을 위해/base64.js을 포함에서 당신은 Base64로 모듈을 사용할 수 있지만 당신은 그것에게 합격해야합니다 당신과 같은 바이트 배열 rQshiftBytes에서 얻을 것이다 :

msg(ws.rQshiftBytes()); 

img.src = "data:image/png;base64," + Base64.encode(data); // str -> data 

을 websockify에서 64 기수의 사용과 관련하여 :

websockify가 무서운 바이너리 데이터를 지원하지 않는 브라우저를 지원하기 위해 데이터를 인코딩하는 base64로 사용 ctly. iOS Safari 및 데스크탑 Safari와 같은 인기있는 Hixie 전용 브라우저 외에도 일부 브라우저 버전에서는 HyBi를 사용하지만 바이너리 지원이 누락되었습니다. 그리고 불행히도 Chrome의 경우 동일한 시간대에 WebIDL 버그가 발생하여 연결하기 전에 바이너리 지원을 감지하지 못했습니다.

Opera의 WebSocket, firefox 3.6-5, IE 8 및 9의 주요 옵션은 web-socket-js입니다. web-socket-js는 HyBi를 지원하지만 바이너리 지원은 없으며, 대상이되는 구형 브라우저의 대부분이 원시 바이너리 형식 (Blob 및 Typed Arrays)을 지원하지 않기 때문에 아마도 그렇지 않을 것입니다.

HyBi 및 이진 데이터를 지원하는 브라우저의 시장 점유율은 현재 매우 낮습니다. 그러나 Websockify는 브라우저가 바이너리 데이터를 지원하는지 여부와 Base64 인 코드/디코드가 필요없는 직접 지원 여부를 감지합니다 (객체 감지 또는 브라우저 버전 감지).

base64 인 코드/디코드의 대기 시간 (및 CPU) 오버 헤드는 매우 낮으며 대개 네트워크 대기 시간에 의해 제거됩니다. base64로 인코딩 된 데이터의 대역폭 오버 헤드는 약 25 %입니다 (즉, 원시 데이터가 33 % 더 커짐). 기본적으로 모든 브라우저에서 웹 소켓을 통해 바이너리 데이터를 제공합니다 (web-socket-js polyfill/shim은 필요한 경우 Websockify가 투명하게 사용함).

+0

다시 한번 자세한 결과를 보내 주셔서 감사합니다. 이미지가 완전히 전송되었는지 어떻게 판단 할 수 있습니까? 더 구체적으로 파이썬에서는 버퍼 크기가 1024 인 일반 소켓을 사용하여 데이터를 보냅니다. 버퍼보다 ​​큰 이미지가 있으면 1024 부분으로 보내집니다. 브라우저에서 이것은 12 번 트리거합니다 (만약 12kb의 이미지) websocket 메시지 이벤트. 이미지를 다시 작성하기 위해이 모든 메시지를 어떻게 결합 할 수 있습니까? 다시 한번 감사합니다. – glarkou

+0

WebSocketServer.send_frames (bufs)는 "버퍼"목록을 사용합니다. 각 버퍼는 클라이언트 (브라우저)에 단일 메시지 (onmessage의 불)로 전달됩니다. onmessage의 수신 대기열에서 모든 것을 전환하면 전체 메시지를 받게됩니다. 작은 덩어리로 send_frames를 호출하는 경우 (또는 send_frames 전체를 우회하는 경우) 메시지를 재구성 (즉, 각 메시지/이미지 앞에 길이 프리픽스 추가) 할 수있는 메커니즘을 프로토콜에 추가해야합니다. 그러나 이것은 WebSocket 기능을 복제하고 있으므로 전체 메시지/이미지와 함께 send_frames를 사용하는 것이 좋습니다. – kanaka

+0

불행히도, 나는 그 일을하는 방법을 이해할 수 없습니다. 지금은 파이썬 서버가'서버 1 '에 이미지를 보내고'서버 2'에서'websockify'를 실행하고 있습니다. 내가'var arr = ws.rQshiftBytes (ws.rQlen()), str = "", chr;을 시도한 메시지를 받았을 때; \t \t \t \t \t \t \t \t 동안 (arr.length> 0) { \t \t \t \t \t = CHR arr.shift(); \t \t \t \t \t str + = String.fromCharCode (chr); \t \t \t \t \t \t} \t \t \t //console.log(str); msg (str); '불행히도. 'ws.on ('message', function()'은 서버에서 보낸 모든 버퍼에 대해 호출되므로 캔버스에 그릴 수있는 그림을 준비 할 수 없는지 확인 할 수 없습니다 .. – glarkou

관련 문제