websocket与nodejs创建web服务器和socket服务


1.首页为了运行h5页面,需要利用NODE开启一个web服务器!

var fs = require('fs');
var events=require('events');
var http=require('http');

var url=require('url');

// 创建服务器
http.createServer( function (request, response) {
// 解析请求,包括文件名
var pathname = url.parse(request.url).pathname;

// 输出请求的文件名
console.log("Request for " + pathname + " received.",pathname.substr(1));

// 从文件系统中读取请求的文件内容
fs.readFile(pathname.substr(1), function (err, data) {
if (err) {
console.log(err);
// HTTP 状态码: 404 : NOT FOUND
// Content Type: text/plain
response.writeHead(404, {'Content-Type': 'text/html;charset=utf-8'});
response.write('页面不存在!');
}else{
// HTTP 状态码: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});

// 响应文件内容
response.write(data.toString());
}
// 发送响应数据
response.end();
});
}).listen(8888);
// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8888/');

 

2.创建h5页面

<!DOCTYPE HTML>
<html>

<head>
<meta charset="utf-8">
<title>webSocket测试</title>

</head>

<body>

<div id="sse">
<a href="javascript:WebSocketTest()">运行 WebSocket</a>
</div>

<input type="text" id="inputBox" />
<button id="submitFunc">发送</button><button onclick="closeWs()">关闭</button>

<div id="content"></div>

<script type="text/javascript">
var ws = null;
var inputBox = document.getElementById('inputBox');
var submitFunc = document.getElementById('submitFunc');
var content = document.getElementById('content');

function WebSocketTest() {
if("WebSocket" in window) {
alert("您的浏览器支持 WebSocket!");

// 打开一个 web socket
ws = new WebSocket("ws://localhost:8124");

ws.onopen = function() {
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("笑傲江湖");
alert("数据发送中...");

submitFunc.onclick = function() {

ws.send(inputBox.value);
alert("数据发送中...");

}
};

ws.onmessage = function(evt) {
var received_msg = evt.data;
console.log('接受的数据', received_msg);
var html=content.innerHTML;
html+=received_msg;
content.innerHTML='<p>'+ html + '</p>';
//alert("数据已接收...");
};

ws.onclose = function() {
// 关闭 websocket
alert("连接已关闭...");
};

} else {

// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}


//获取信息发送
function closeWs(){
if(ws!=null){
ws.close();
}else{
alert('你还没开启');
}

}

</script>
</body>

</html>

 

3.利用net模块创建socket服务

 

const crypto = require('crypto');
const net = require('net');
var clientList = [];
var this_client = null;
var options = {
allowHalfOpen: false,
pauseOnConnect: false
}

let tcpServer = net.createServer(options);

//计算websocket校验
function getSecWebSocketAccept(key) {
return crypto.createHash('sha1')
.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
.digest('base64');
}

//掩码操作
function unmask(buffer, mask) {
const length = buffer.length;
for(var i = 0; i < length; i++) {
buffer[i] ^= mask[i & 3];
}
console.log('解码后的数据', buffer.toString('utf8'));
}

tcpServer.on('listening', () => {
console.log('开始监听');
});

tcpServer.on('connection', (socket) => {
console.log('连接已建立' + '\n', socket.name);

//启动心跳机制
/*var isOnline = !0;
var keepAliveTimer = socket.timer = setInterval(()=>{
if(!isOnline){
this_client = socket;
quit(socket.nick);
return;
}
if(socket.writable){
isOnline = !1;
socket.write('::');
}else{
this_client = socket;
quit(socket.nick);
}
},3000);

if(socket._handle==null){
isOnline = !0;
return;
}*/

tcpServer.getConnections((err, count) => {
if(err) {
console.warn(err);
} else {
console.log(`当前有${count}个连接`);
}
});

socket.on('data', (data) => {
this_client = socket;
if(clientList.indexOf(socket) > -1) {

let buffer = data;

let fin = (buffer[0] & 0b10000000) === 0b10000000;
//取第一个字节的后四位,得到的一个是十进制数
let opcode = buffer[0] & 0b00001111;
//取第二个字节的第一位是否是1,判断是否掩码操作
let mask = buffer[1] & 0b100000000 === 0b100000000;
//载荷数据的长度
let payloadLength = buffer[1] & 0b01111111;
//掩码键,占4个字节
let maskingKey = buffer.slice(2, 6);
//载荷数据,就是客户端发送的实际数据
let payloadData = buffer.slice(6);
console.log('客户端发送的实际数据', payloadData.toString('utf8'));

//对数据进行解码处理
unmask(payloadData, maskingKey);

//向客户端响应数据
let send = Buffer.alloc(2 + payloadData.length);
//0b10000000表示发送结束
send[0] = opcode | 0b10000000;
//载荷数据的长度
send[1] = payloadData.length;
payloadData.copy(send, 2);

var now = new Date();

broadcast(send, socket);

/*const buf2 = Buffer.from('后台传过来的时间:'+now, 'utf8');
const buf=Buffer.alloc(2+buf2.length);
buf[0]=opcode | 0b10000000;
buf[1]=buf2.length;
buf2.copy(buf,2);*/

/*for(var i=0;i<clientList.length;i++){
let client=clientList[i];
if(client._handle==null){
clientList.splice(clientList.indexOf(client), 1);
i--;
}
}*/

/* if(send=='end'){
this.close();
}

for(var i=0;i<clientList.length;i++){
console.log('剩余个数:',clientList.length);
let client=clientList[i];
//console.log('返回数据中---',client);
console.log(send);

client.write(send);
}*/

} else {

data = data.toString();
if(data.match(/Upgrade: websocket/)) {
let rows = data.split('\r\n');
//去掉第一行的请求行
//去掉请求头的尾部两个空行
rows = rows.slice(1, -2);
let headers = {};
rows.forEach(function(value) {
let [k, v] = value.split(': ');
headers[k] = v;
});
//判断websocket的版本
if(headers['Sec-WebSocket-Version'] == 13) {
let secWebSocketKey = headers['Sec-WebSocket-Key'];
//计算websocket校验
let secWebSocketAccept = getSecWebSocketAccept(secWebSocketKey);
//服务端响应的内容
let res =
'HTTP/1.1 101 Switching Protocols \r\n' +
'Upgrade: websocket \r\n' +
'Sec-WebSocket-Accept: ' + secWebSocketAccept + '\r\n' +
'Connection: Upgrade \r\n' +
'\r\n';

console.log('发送给客户端协议', res);
//给客户端发送响应内容
socket.write(res);
//socket.name = socket.remoteAddress + ':' + socket.remotePort;
clientList.push(socket);

}
}
}

});

socket.on('disconnect', function() { // 这里监听 disconnect,就可以知道谁断开连接了
console.log('disconnect: ' + socket.id);
});

socket.on('error', (err) => {
console.warn('错误', err);
socket.destroy();
});

/*socket.on('close', function(data) {
console.log('客户端关闭了!',data);
//clientList.splice(clientList.indexOf(socket), 1);
// socket.remoteAddress + ' ' + socket.remotePort);
});*/

//结束
socket.on('end', () => {
console.log('' + socket + '-quit'); //如果某个客户端断开连接,node控制台就会打印出来
//this.destroy();
clientList.splice(clientList.indexOf(socket), 1);
});

function broadcast(message, client) {
var cleanup = []; //断开了的客户端们
for(var i = 0; i < clientList.length; i++) {

//检查socket的可写状态
if(clientList[i].writable) {
// 把数据发送给其他客户端
if(message.toString().length > 2) {
clientList[i].write(message);
}
} else {
cleanup.push(clientList[i]);
clientList[i].destroy();
}
}
/*删除掉服务器的客户端数组中,已断开的客户端*/
for(var i = 0; i < cleanup.length; i++) {
clientList.splice(clientList.indexOf(cleanup[i]), 1);
}
}
});

tcpServer.on('close', () => {
console.log('close');
});

tcpServer.listen(8124);

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM