const http = require('http'); var crypto = require("crypto"); var util = require("util"); const server = http.createServer((req, res) => { console.log(req, res); }).listen(8080); server.on('upgrade', function(req, socket, upgradeHead) { console.log('aaaaaaaaaaa', upgradeHead.toString()); var key = req.headers['sec-websocket-key']; key = crypto.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64"); var headers = [ 'HTTP/1.1 101 Switching Protocols', 'Upgrade: websocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + key ]; socket.setNoDelay(true); socket.write(headers.join(" ") + " ", 'ascii'); socket.on('data', function(data) { console.log(data); dataHandle(data); }); socket.on('close', function(e) { }); socket.on('error', function(e) { }); }); function handleDataStat(data) { var dataIndex = 2; //数据索引,因为第一个字节和第二个字节肯定不为数据,所以初始值为2 var secondByte = data[1]; //代表masked位和可能是payloadLength位的第二个字节 var hasMask = secondByte >= 128; //如果大于或等于128,说明masked位为1 secondByte -= hasMask ? 128 : 0; //如果有掩码,需要将掩码那一位去掉 var dataLength, maskedData; //如果为126,则后面16位长的数据为数据长度,如果为127,则后面64位长的数据为数据长度 if (secondByte == 126) { dataIndex += 2; dataLength = data.readUInt16BE(2); } else if (secondByte == 127) { dataIndex += 8; dataLength = data.readUInt32BE(2) + data.readUInt32BE(6); } else { dataLength = secondByte; } //如果有掩码,则获取32位的二进制masking key,同时更新index if (hasMask) { maskedData = data.slice(dataIndex, dataIndex + 4); dataIndex += 4; } //计算到此处时,dataIndex为数据位的起始位置,dataLength为数据长度,maskedData为二进制的解密数据 return { index: dataIndex, totalLength: dataLength, length: dataLength, maskedData: maskedData, opcode: parseInt(data[0].toString(16).split("")[1], 16) //获取第一个字节的opcode位 }; } function dataHandle(data) { var stat = handleDataStat(data); var datas = []; console.log(stat); //如果opcode为9,则发送pong响应,如果opcode为10则置pingtimes为0 if (stat.opcode === 9 || stat.opcode === 10) return; var result; if (stat.maskedData) { result = new Buffer(data.length - stat.index); for (var i = stat.index, j = 0; i < data.length; i++, j++) { //对每个字节进行异或运算,masked是4个字节,所以%4,借此循环 result[j] = data[i] ^ stat.maskedData[j % 4]; } } else { result = data.slice(stat.index, data.length); } datas.push(result); stat.length -= (data.length - stat.index); var buf = Buffer.concat(datas, stat.totalLength); console.log("sss:", buf.toString()); console.log("sss:", stat.length); //当长度为0,说明当前帧为最后帧 if (stat.length == 0) { var buf = Buffer.concat(datas, stat.totalLength); } }