服务端代码

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);

最新文章

  1. [调整] Firemonkey TEdit 避免按下立即弹出键盘的问题
  2. 【QT】C++ GUI Qt4 学习笔记2
  3. MySQL压缩包安装
  4. eclipse配置jdk问题
  5. [翻译] - &lt;Entity Framework&gt; - 直接执行数据库命令
  6. js cookie使用方法详解
  7. Codeforces Round #270(利用prim算法)
  8. python-igraph on windows10 64bit
  9. android 在代码中使用 #ffffff 模式 设置背景色
  10. mysql_索引
  11. mplayer用法收集【转】
  12. pandas.Dataframe复杂条件过滤
  13. pb中遍历查询数据库数据问题(数据库为 sql server)
  14. javascript多种继承方式(函数式,浅复制,深复制,函数绑定和借用)
  15. js 判断l对象类型
  16. ASP.NET项目在IIS上使用虚拟目录
  17. 【linux基础】ubuntu如何查看linux的内核版本和系统版本
  18. 关于 Table 表格那些三两事儿
  19. FPGA的过去,现在和未来
  20. win10系统安装Oracle11报错不满足最低要求

热门文章

  1. Enum枚举的使用实现
  2. hover和position共用出现的问题
  3. vim设置golang语法高亮 (Centos)
  4. Android Studio 优秀插件:GsonFormat
  5. KafkaStream低级别API
  6. Docker 配置国内镜像
  7. BZOJ 1345: [Baltic2007]序列问题Sequence
  8. SpringBoot自动注入分析
  9. 使用malloc函数或new运算符为链表结点分配内存空间
  10. mysql启动错误1067进程意外终止的解决方法