开工前准备工作
1.前后端约定好长链接的URL
(本文举例:域名-127.0.0.1,端口号-8081,路径-/test)
2.前后端约定好发送message指令的格式
(本文格式为 {‘userId’:’ ', ‘message’: ’ '} )
前端封装可保持长链接的websocket构造函数
1.创建一个普通的websocket连接
function createWebsocket(link) {
// 检查浏览器是否支持websocket
if (!('WebSocket' in window) && !('MozWebSocket' in window)) {
alert('浏览器暂不支持websocket');
} else {
var ws = new WebSocket(link);
initWs(); // 初始化websocket相关的事件监听
}
}
2.初始化websocket相关的事件监听
function initWs() {
// 连接服务器成功触发
ws.onopen = function(e){
logStatus("连接服务器成功"); // 打印log工具函数
...// 自定义操作
// 开始心跳
heartSend.start();
}
// 接收服务器的消息触发
ws.onmessage = function(e){
let message = "接收到一条服务端信息,message:"+e.data+"";
logStatus(message);
...// 自定义操作
// 心跳计时器重启
heartSend.reset().start();
}
// 连接关闭触发
ws.onclose = function(e){
logStatus("连接关闭:" + e.code + e.reason);
heartSend.reset();// 停止心跳
...// 自定义操作
}
// 连接异常触发
ws.onerror = function(e){
logStatus("连接出错,error:" + e.data);
logStatus("正在尝试重新连接");
heartSend.reset();// 停止心跳
...// 自定义操作
reconnect(url);
}
// 封装自定义关闭连接[举例]
ws.closeForUse = function(bool){
// 参数、控制逻辑可依据业务具体需要自行封装,这里bool仅仅举例实现自动断开重连功能
ws.close();
bool && logStatus("正在尝试重新连接");
bool && reconnect(url);
}
// 封装发送信息方法[同理举例,根据业务需要灵活封装即可]
ws.sendForUse = function(clientId, msg, ...param){
let msg = {
'clientId': clientId,
'msg': msg,
...
}
ws.send(msg);
logStatus('send: ' + msg);
}
}
3.添加心跳机制[主动与服务端保持连接]
事出有因:长时间无信息通信,服务端会自动断开连接,因此可添加心跳机制间隔一段时间像服务端发送消息,主动保持联络。
var heartSend = {
timeout: 200000, // 自定义
timeObj: null,
reset: function(){
clearTimeOut(this.timeOutObj);
},
start: function(){
this.timeOutObj = setTimeOut(function(){
var msg = {
'keepConnect': 'on'};
logStatus('发送心跳信息');
ws.send(msg);
}, this,timeout)
}
}
3.监听窗口关闭,处理异常
window.onbeforeunload = function(){
ws.close(); // 关闭长连接
}
3.断开、连接异常 自动重连
function reconnect (url) {
ws = null; // 清空上次的websocket
setTimeOut(function(){
createWebsocket(url)
}, 2000)
}
4.客户端代码示例
export default function(domain) {
let ws = null;
let link = 'ws://' + domain + ':8081' + '/test';
let WsFunc = function() {
function createWebsocket(link) {
...};
function initWs() {
...};
var heartSend = {
...};
function reconnect(link) {
...};
createWebsocket(link); // 创建一个长连接
// 监听窗口关闭时间,窗口关闭,主动关闭websocket连接
window.onbeforeunload = function(){
ws.close(); // 关闭长连接
}
return ws;
}
let logStatus = function(msg) {
console.log(msg + '---' + new Date().toLocaleString());
}
window.top.wsObj = new WsFunc();
}
后端demo[简易]
var ws = require("nodejs-websocket");
var server = ws.createServer(function(obj){
obj.on("text", function (str) {
console.log("连接")
obj.sendText("xxxx");
...
})
obj.on("close", function (code, reason) {
console.log("关闭")
});
obj.on("error", function (code, reason) {
console.log("异常")
});
}).listen(8001)