我一直在尝试实现从特定计算机接收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地址上运行。
谢谢
答案 0 :(得分:1)
是的,你完全可以做到这一点。对于初学者来说,一个令人困惑的事情是websocket初始请求不会进入你的data
事件。它将进入upgrade
事件。有关详细信息,请参阅node docs。
在您的实例中,您的其他服务器需要首先使用websocket upgrade
请求联系此服务器,并且将建立该连接。然后,当您收到POST请求时,您需要在已经存在的来自其他服务器的websocket请求中重新发送该数据。
您最好的选择是使用现有的库,例如ws
。您可以使用此库附加到现有的http服务器。 See example here。 (示例说明了,但如果你看,我相信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 '';
}