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("\r\n") + "\r\n\r\n", '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);
}
}