2013-01-25 2 views
2

socket.io 대신 웹 소켓 용으로 자체 구현을 작성하고 있습니다.기본 Websocket 프레임을 어떻게 처리합니까?

나는 좋은 핸드 셰이크를 가지고 있지만 클라이언트가 서버로 보낼 때 유용한 데이터로 변환하는 방법을 알 수 없다. 그것은 대상입니까? 그것은 문자열인가? 워드 프로세서는 V8 힙 외부의 원시 메모리 위치 배열이라고합니다. ...?

enter image description here

(클라이언트 하드 문자열 코딩) 일례를 작동

var http = require("http"); 
var crypto = require("crypto"); 
var server = http.createServer(); 
server.on("upgrade", function (req, socket, upgradeHead) { 
    var crypto = require("crypto"); 
    var shasum = crypto.createHash("sha1"); 
    shasum.update(req.headers["sec-websocket-key"]); 
    shasum.update("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 
    var hash = shasum.digest("hex"); 
    var myVal = new Buffer(hash, "hex").toString('base64'); 

    var head = ""; 
    head += "HTTP/1.1 101 Switching Protocols\r\n"; 
    head += "Connection: Upgrade\r\n"; 
    head += "Upgrade: WebSocket\r\n"; 
    head += "Sec-WebSocket-Accept: " + myVal + "\r\n\r\n"; 

    socket.setEncoding("utf8"); 
    socket.write(head); 

    socket.ondata = function (data, start, end) { 
     var data = data.toString("utf8", start, end); 
     console.log(" start: " + start + "\n end: " + end + "\n data: " + data); 
    }; 
}); 
server.on("request", function (req, res) { 
    if (req.url === "/e") 
     process.exit(); 
    if (req.url.indexOf("favicon") !== -1) 
     return; 

    var html = "\ 
       <!DOCTYPE html>\r\n\ 
       <html>\r\n\ 
        <head>\r\n\ 
         <script>\r\n\ 
          var connection = new WebSocket('ws:localhost:80');\r\n\ 
          connection.onopen = function() {\r\n\ 
           console.log('OPEN SUCCESS');\r\n\ 
           connection.send('I am a message from the client.');\r\n\ 
          };\ 
          connection.onmessage = function(msg) {\r\n\ 
           console.log(msg);\r\n\ 
          }\r\n\ 
          connection.onerror = function (e) { console.log('ERROR'); console.log(e); };\r\n\ 
          connection.onclose = function (e) { console.log('CLOSE'); console.log(e);};\r\n\ 
         </script>\r\n\ 
        </head>\r\n\ 
       </html>"; 
    res.writeHead(200, { "Content-Type": "text/html" }); 
    res.write(html); 
    res.end(); 
}); 
server.listen(80); 

node docs - socket.on(data, myFunc);

node docs - Buffer object

Tutorial I am using

Detailed WebSocket Documentation

eazy-peezy wikipedia handshake explanation

답변

8

주요 문제 17,451,515,는 튜토리얼이 기록 된 이후 웹 소켓 프로토콜이 많이 발전했다고한다. 링크 된 스펙을 읽으면 섹션 5.2에서 데이터 프레임에 대해 설명합니다. 데이터 횡설수설하게

http://tools.ietf.org/html/rfc6455#page-28

주요 문제는 보낼 때 프레임을 처리해야하므로 데이터가 자동으로 마스크이다.

다음은 샘플 코드를 디코딩하는 예입니다. 더 큰 길이를 커버하기 위해 확장해야하고 스펙의 다른 부분을 처리해야합니다.

socket.ondata = function (data, start, end) { 
    var message = data.slice(start, end); 
    var FIN = (message[0] & 0x80); 
    var RSV1 = (message[0] & 0x40); 
    var RSV2 = (message[0] & 0x20); 
    var RSV3 = (message[0] & 0x10); 
    var Opcode = message[0] & 0x0F; 
    var mask = (message[1] & 0x80); 
    var length = (message[1] & 0x7F); 

    var nextByte = 2; 
    if (length === 126) { 
    // length = next 2 bytes 
    nextByte += 2; 
    } else if (length === 127){ 
    // length = next 8 bytes 
    nextByte += 8; 
    } 

    var maskingKey = null; 
    if (mask){ 
    maskingKey = message.slice(nextByte, nextByte + 4); 
    nextByte += 4; 
    } 

    var payload = message.slice(nextByte, nextByte + length); 

    if (maskingKey){ 
    for (var i = 0; i < payload.length; i++){ 
     payload[i] = payload[i]^maskingKey[i % 4]; 
    } 
    } 

    console.log(payload.toString()); 
}; 
+0

남자, 당신은 나를 가장 어려운 부분으로 끌어 당기고 올바른 길로 가야합니다. 정말 고마워. 이것으로 많은 것을 배웠습니다. – user1873073

+0

@ user1873073 문제가 없습니다! 나머지는 행운을 빌어 요. – loganfsmyth

+0

나는 socket.write (payload.toString())로 보낸 사람에게 메시지를 다시 보내려고했다. 그리고 나는 (! Websocket 프로토콜 오류)있어. – ket

관련 문제