Node.js同时运行HTTP服务器和Web Socket服务器

3
我一直试图实现一个HTTP服务器,它可以接收来自特定计算机的POST请求。然后,HTTP服务器将提取接收到的消息正文,并使用Web套接字将正文数据发送到另一个客户端。
以下是HTTP服务器的代码:
    var http=require('http');


    var server = http.createServer(function(request, response){
        var msgbody='';
        if(request.method == "POST"){
             request.on('data', function(data){
                  msgbody=data;

                  //upon receiving POST request send msgbody to the client using websockets
             });
        }
    }).listen(80);

您好,您能否给我一些关于如何正确实现WebSockets部分与运行的HTTP服务器相结合的见解呢?HTTP服务器和WebSockets服务器需要在同一个IP地址和端口上运行。

谢谢!

1个回答

1

是的,你完全可以这样做。首先,有一个令人困惑的事情是,websocket初始请求不会出现在你的data事件中,它将出现在upgrade事件中。更多细节请参见node文档

在你的实例中,你的另一个服务器需要先使用websocket upgrade请求联系这个服务器,建立连接。然后当你收到POST请求时,你需要重新发送数据通过已经存在的来自另一个服务器的websocket请求。

你最好使用现有库,比如ws。你可以使用此库附加到现有的http server。这里看例子。(例子说express,但如果你看一下,我相信ws库实际上是附加到一个常规的node http server)

如果你想了解它的工作原理,或者你非常想自己编写websocket服务器:这是完全可能的。以下是一个简单的例子,演示了如何从客户端接收数据帧。我从来没有真正开始制作发送帧,但this MDN page详细解释了整个过程。

server.on('upgrade', handleWS);

function handleWS(request, socket, buf) {
    var key = getHeader(request, 'Sec-WebSocket-Key');
    var magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
    var shasum = crypto.createHash('sha1');
    shasum.update(key + magic);
    var akey = shasum.digest('base64');
    var resp = ['HTTP/1.1 101 Switching Protocols',
        'Upgrade: websocket',
        'Connection: Upgrade',
        'Sec-WebSocket-Accept: ' + akey, '', ''].join('\r\n');
    console.log(key, resp);
    socket.write(resp);
    var inbuff = '';
    socket.on('data', function (buf) {
        var fin = buf.readUInt8(0) >> 7;
        var opcode = buf.readUInt8(0) & 15; //0=cont, 1=text, 2=binary
        var mask = buf.readUInt8(1) >> 7, bmask;
        var len = buf.readUInt8(1) & 127;
        var i = 2;
        if (len === 126) { len = buf.readUInt16BE(i); i += 2; }
        else if (len === 127) {
            len = (buf.readUInt32BE(i) << 32) + buf.readUInt32BE(6);
            i += 8;
        }
        if (mask) { bmask = buf.slice(i, i + 4); i += 4; }
        data = buf.slice(i, i + len);
        if (mask) for (var j = 0; j < data.length; j++) 
            data[j] = data[j] ^ bmask[j % 4];
        if (opcode === 1) data = data.toString('utf8');
        // todo: handle fragmentation
        console.log(fin, opcode, mask, len, data);
    })
}
function getHeader(req, key) {
    var keyl = key.toLowerCase()
    for (var k in req.headers) if (k.toLowerCase() === keyl) return req.headers[k];
    return '';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接