是的,你完全可以做到。对于初学者来说,一件令人困惑的事情是 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 '';
}