
服务端代码
websocket.js
'use strict' const WebSocket = require('ws'); const connections = new Map(); const Constr = function(port) { const self = this; self.webSocket = new WebSocket.Server({ port: port }); }; Constr.prototype.connect = function() { const self = this; self.webSocket.on('connection', function connection(ws) { try { ws.on('message', function incoming(message) { try { if (connections.size > 2000) { ws.send(1); ws.close(); return; } ws.send(0); if (connections.get(message) && connections.get(message).ws.readyState == WebSocket.OPEN) { connections.get(message).date = Date.now(); connections.get(message).ws.isAlive = true; console.log(message + ':上次心跳时间' + connections.get(message).date); return; } connections.set(message, { ws: ws, date: Date.now(), }); console.log('客户端imei:' + message + '握手、心跳成功!时间:' + connections.get(message).date); ws.on('close', function close() { console.log('连接关闭 ' + message) // ws.reconnect(); if (connections.get(message)) { connections.delete(message); } ws.close(); }); ws.on('error', function close() { console.error(message + ':出现错误!强制下线'); connections.get(message) .ws .close(); }); // 服务器接受pong消息++huanglong,确定mtk接受ping,并pong服务器后打开 // ws.on('pong', function() { // connections.get(message).date = Date.now(); // connections.get(message).ws.isAlive = true; // console.log('上次接收pong时间' + connections.get(message).date); // }); } catch (e) { console.error('on message error:', e); } }); }catch (e) { console.error('on connection error:', e); } }); self.webSocket.on('error',function(){ console.log('error'); }); }; Constr.prototype.send = function(obj) { console.log('下推消息:' + JSON.stringify(obj)); const imeiArray = obj.imei.split(','); for (let i = 0; i < imeiArray.length; i++) { try { if (connections.get(imeiArray[i]) && connections.get(imeiArray[i]).ws.readyState === WebSocket.OPEN) { console.log(imeiArray[i] + ':连接状态' + connections.get(imeiArray[i]).ws.readyState); connections.get(imeiArray[i]).ws.send(obj.str); } else { console.log('imei:' + imeiArray[i] + 'socket关闭!'); connections.delete(imeiArray[i]); } } catch (e) { console.log('发送消息发生严重错误!imei:' + imeiArray[i]); } } }; Constr.prototype.heartbeatCheck = function() { console.log('心跳检查:当前握手连接数为' + connections.size + '客户端:' + connections.keys().toString()); if (connections.size === 0) { return; } connections.forEach(function (value, key) { if (Date.now() - value.date > 60000) { connections.delete(key); try { value.ws.close(); }catch (e) { console.error('close error', e); } } // ++huanglong,暂时关闭ping机制,确定mtk接受ping,并pong服务器后打开 // if (value.ws.isAlive === false) return value.ws.terminate(); // value.ws.isAlive = false; // value.ws.ping(function() { // value.ws.send(2); // }); }); }; // Constr.prototype.testyuyin2 = function() { // connections.forEach(function(value) { // value.ws.send('测试语音'); // }); // }; module.exports = Constr;
app.js
const Ws = require('./app/middleware/websocket');
const ws = new Ws(8080);
try {
ws.connect();
} catch (e) {
console.error('ws connect error:', e);
}
console.log("WebSocket建立完毕")
客户端
const WebSocket = require('ws');
var lockReconnect = false;//避免重复连接
var wsUrl = "ws://127.0.0.1:8080";
var ws;
var tt;
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch (e) {
console.log('catch' + e);
reconnect(wsUrl);
}
}
function init() {
ws.onclose = function () {
console.log('链接关闭');
reconnect(wsUrl);
};
ws.onerror = function () {
console.log('发生异常了');
reconnect(wsUrl);
};
ws.onopen = function () {
//心跳检测重置
heartCheck.start();
};
ws.onmessage = function (event) {
//拿到任何消息都说明当前连接是正常的
console.log('接收到消息' + JSON.stringify(event.data));
heartCheck.start();
}
}
function reconnect(url) {
if (lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}
//心跳检测
var heartCheck = {
timeout: 3000,
timeoutObj: null,
serverTimeoutObj: null,
start: function () {
// console.log('start');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
ws.send("666666");
self.serverTimeoutObj = setTimeout(function () {
// console.log(111);
// console.log(ws);
ws.close();
// createWebSocket();
}, self.timeout);
}, this.timeout)
}
}
createWebSocket(wsUrl);