Node.js 同时运行一个 http 服务器和 web socket 服务器
Posted
技术标签:
【中文标题】Node.js 同时运行一个 http 服务器和 web socket 服务器【英文标题】:Node.js running an http server and web socket server concurrently 【发布时间】:2018-04-22 08:44:12 【问题描述】:我一直在尝试实现一个从特定计算机接收 POST 请求的 HTTP 服务器。然后,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);
能否请您提供一些关于如何在运行的 HTTP 服务器旁边正确实现 Web 套接字部分的见解? HTTP 服务器和 Web 套接字服务器需要在相同的端口和 IP 地址上运行。
谢谢
【问题讨论】:
【参考方案1】:是的,你完全可以做到。对于初学者来说,一件令人困惑的事情是 websocket 初始请求不会出现在您的 data
事件中。它将来到upgrade
事件。详情请见node docs。
在您的实例中,您的其他服务器将需要首先使用 websocket upgrade
请求联系该服务器,然后将建立该连接。然后,当您收到 POST 请求时,您需要通过来自另一台服务器的现有 websocket 请求重新发送该数据。
您最好的选择绝对是使用现有的库,例如 ws
。您可以使用此库附加到现有的 http 服务器。 See example here。 (例子是 express,但如果你看我相信ws
库实际上是附加到一个常规节点 http 服务器)
如果您对它的工作原理感到好奇,或者如果您一心想编写自己的 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 '';
【讨论】:
以上是关于Node.js 同时运行一个 http 服务器和 web socket 服务器的主要内容,如果未能解决你的问题,请参考以下文章
为什么同时运行VSCode可以显着提高Windows服务器上的Node.js性能?
Node.JS、Express 和 Heroku - 如何处理 HTTP 和 HTTPS?