本片文章实现的功能是后端程序给指定的用户通过webSocket推送消息。根据前端用户登录时给后台传递用户ID,然后在后台将用户ID和对应的webSocketSession存储起来,用于推送消息时使用。
一、引入sockjs-1.0.3.js
<script type="text/javascript" src="../js/webSocket/sockjs-1.0.3.js"></script>
二、自己封装的WebSocket组件
/**
* 自己封装的WebSocket组件
* @param factory
* @returns
*/
(function(factory) {
// 启用严格模式
"use strict";
// 环境探测语句:如果采用了AMD异步加载模块的方式
if (typeof define === 'function' && define.amd) {
// 启用AMD模块化
define([ 'jquery' ], factory);
} else if (typeof exports === 'object' && typeof require === 'function') {
// 如果采用了CommonJS的模块加载方式,启用CommonJS模块化
factory(require('jquery'));
} else {
// 原生JS调用工厂模式
factory(jQuery);
}
}
(function($, undefined) {
// 启用严格模式
"use strict";
var DIYWebSocket = function(opt) {
this.options = $.extend(true, {}, DIYWebSocket.defaultOptions, opt);
// 原生支持websocket的地址
this.options.wsUrl = this.options.webSocketProtocol
+ this.options.websocketServiceDomain
+ "/webSocketService"
+ (this.options.clientID ? "?clientID=" + this.options.clientID : "");
// 不支持websocket使用sockjs连接的地址
this.options.wsSockjsUrl = this.options.webSocketJSProtocol
+ this.options.websocketServiceDomain
+ "/webSocketService/sockjs"
+ (this.options.clientID ? "?clientID=" + this.options.clientID : "");
this.ws = this.createWebSocket();
};
/**
* 默认配置
*/
DIYWebSocket.defaultOptions = {
// webSocket客户端ID
clientID : "",
// webSocket协议
webSocketProtocol : "",
// 不支持websocket使用sockjs连接的协议
webSocketJSProtocol : "",
// webSocket服务域名
websocketServiceDomain : "",
// 未收到消息多少秒后,给后端服务发送消息,(心跳间隔默认20秒)
timeout : 40000,
// 前端发送消息后,未收到消息超时时间,默认60000毫秒
serverTimeout : 60000,
// 连接间隔时间
intervalTime : 6000,
// 收到消息回调函数
onMessageCallBack : function(msg) {
},
// 收到消息回调函数
errorCallBack : function() {
}
}
DIYWebSocket.prototype.createWebSocket = function() {
try {
var ws;
if ('WebSocket' in window) {
ws = new WebSocket(this.options.wsUrl);
} else {
// sockjs是javascript库,提供了服务器和浏览器间的双向通信,优先使用websocket通信,当浏览器不支持时,则自动改为轮询与服务器通信。
ws = new SockJS(this.options.wsSockjsUrl);
}
this.initEventHandle(ws);
return ws;
} catch (e) {
this.reconnect();
throw e;
}
};
DIYWebSocket.prototype.initEventHandle = function(ws) {
var obj = this;
ws.onclose = function() {
console.info("连接关闭onclose");
obj.closeWebSocket();
};
ws.onerror = function() {
console.info("传输异常");
obj.closeWebSocket();
obj.options.errorCallBack.call(this);
};
ws.onopen = function() {
// 心跳检测重置
obj.heartCheck();
};
ws.onmessage = function(event) {
var json;
try {
json = eval('(' + event.data + ')');
} catch (e) {
json = event.data;
}
console.info("收到的消息" + json);
obj.options.onMessageCallBack.call(this, json);
// 拿到任何消息都说明当前连接是正常的,心跳检测重置
obj.heartCheck();
};
};
/**
* 连接端webSocket服务
*/
DIYWebSocket.prototype.reconnect = function() {
var obj = this;
// 检测是否已连接
if (obj.options.lockReconnect) {
return;
}
obj.options.lockReconnect = true;
// 没连接上会一直重连
setTimeout(function() {
// 连接服务端
obj.createWebSocket();
console.info("重连接websocket");
obj.options.lockReconnect = false;
}, obj.options.intervalTime);
};
/**
* 给后台服务发送消息
*/
DIYWebSocket.prototype.sendMessage = function(msg) {
var obj = this;
obj.ws.send(msg);
};
/**
* 心跳检测
*/
DIYWebSocket.prototype.heartCheck = function() {
var obj = this;
obj.heartReset();
obj.heartStart();
};
/**
* 开始心跳检测
*/
DIYWebSocket.prototype.heartStart = function() {
var obj = this;
obj.timeoutID = setTimeout(function() {
// 发送一个消息,后端收到后,返回消息,onmessage拿到返回的消息就说明连接正常
obj.sendMessage("HeartBeat");
console.info("客户端发送心跳:" + new Date());
// 如果超过一定时间还没收到消息,说明后端主动断开了
obj.serverTimeoutID = setTimeout(function() {
// 关闭ws.close()
obj.closeWebSocket();
}, obj.options.serverTimeout);
}, obj.options.timeout);
};
/**
* 重置心跳检测
*/
DIYWebSocket.prototype.heartReset = function() {
console.info("重置心跳检测");
var obj = this;
clearTimeout(obj.timeoutID);
clearTimeout(obj.serverTimeoutID);
};
/**
* 关闭webSocket
*/
DIYWebSocket.prototype.closeWebSocket = function() {
console.info("关闭webSocket");
var obj = this;
obj.ws.close();
};
/**
* 使用jquery方式对外提供调用
*/
$.extend({
bindWebSocket : function(options) {
return new DIYWebSocket(options);
}
})
}));
三、页面使用
//websocket实例
var ws = $.bindWebSocket({
// webSocket客户端ID
clientID : "${loginPersonID}",
// webSocket协议,当项目使用https协议访问时,webSocket使用wss协议访问
webSocketProtocol : "ws://",
// 不支持websocket使用sockjs连接的协议,跟随项目协议访问方式一致
webSocketJSProtocol : "http://",
// webSocket服务域名(有端口号时,需要携带端口号)
websocketServiceDomain : "${websocketServiceDomain}",
// 收到消息回调函数
onMessageCallBack : function(msg) {
//处理服务器返回的消息
}
});