服务端和客户端之间的实时通信采用的是WebSocket+Stomp+SockJS
WebSocket 协议提供了通过一个套接字实现全双工通信的功能。一次连接以后,会建立tcp连接,后续客户端与服务器交互为全双工方式的交互方式,客户端可以发送消息到服务端,服务端也可将消息发送给客户端。
SockJS 是 WebSocket 技术的一种模拟。主要是为了应对许多浏览器不支持WebSocket协议的问题,设计了备选SockJs。开启并使用SockJS后,它会优先选用Websocket协议作为传输协议,如果浏览器不支持Websocket协议,则会在其他方案中,选择一个较好的协议进行通讯。
STOMP 面向消息的简单文本协议。websocket定义了两种传输信息类型: 文本信息和二进制信息。类型虽然被确定,但是他们的传输体是没有规定的。所以,需要用一种简单的文本传输类型来规定传输内容,它可以作为通讯中的文本传输协议,即交互中的高级协议来定义交互信息。
STOMP本身可以支持流类型的网络传输协议: websocket协议和tcp协议。
Stomp还提供了一个stomp.js,用于浏览器客户端使用STOMP消息协议传输的js库。
具体流程是:
首先
通过sockjs建立连接对象;var socket=new SockJS("/endpointChat");
通过Stomp.over()方法获取 STOMP 子协议的客户端对象 var stompClient = Stomp.over(socket);
向服务器发起websocket连接并发送CONNECT帧 通过client.connect(headers, connectCallback, errorCallback)方法建立连接,connect方法的第一个参数headers表示客户端的认证信息,connectCallback 表示连接成功时的回调方法;errorCallback 表示连接失败时的回调方法。
通过subscribe来订阅一个消息
若要从客户端主动断开连接,可调用 disconnect() 方法
连接成功后,客户端可使用 send() 方法向服务器发送信息
// 在项目优化过程中,希望可以直接使用webpack的代理模式,直接通过代码进行请求,这样页面就不需要进行socket地址的配置。
/*
优点:
(1)页面减少全量变量的配置;
(2)系统方法调用的统一性,和其他普通的接口调用代理一致。
缺点:
(1)由于在页面中配置的代理,而不是直接请求http:xxxx,导致需要在代理服务器中(例如ngnix)上多添加一个代理配置。相当于把以前http的直接请求方式变成代理转发请求。
具体更改模式为:
1、在自定义的websocket.js文件中,创建SockJS对象:
新写法:const socket = new SockJS('/bullet');// 连接SockJS的endpoint名称为"bullet"
旧写法:let socket = new SockJS('http://'+config.webSocketUrl+'/bullet');//连接SockJS的endpoint名称为"bullet"
2、在项目根目录下的config/index.js文件中(vue-cli2.0),或者vue.config.js(vue-cli3.0)添加代理配置即可。
*/
'/stomp': {
target: 'http://10.194.14.169:32009',
ws: true
},
在webSocket中加入了心跳机制,主要是为了解决在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件。这样则导致服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。所以通过心跳机制来检测客户端和服务端是否处于正常的链接状态。
实现心跳检测的思路是:每隔一段固定的时间,向服务器端发送一个ping数据,如果在正常的情况下,服务器会返回一个pong给客户端,如果客户端通过onmessage事件能监听到的话,说明请求正常,使用了一个定时器,每隔30秒的情况下,如果网络断开,在指定的时间内服务器端并没有返回心跳响应消息,说明服务器端断开了,可以使用ws.close关闭连接,在一段时间后可以通过 onclose事件监听到。因此在onclose事件内,我们可以调用 reconnect事件进行重连操作。
sockjs-client
后端向前端进行消息推送,前端需要接收这些推送消息,并显示出来。这里接收推送消息需要使用sockjs的固定存储库:sockjs-client。
SockJS是一个JavaScript库,提供跨浏览器JavaScript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。
服务端:sockjs-node
客户端:sockjs-clien
node-static是Node.js兼容HTTP静态文件服务器处理模块,提供内置的缓存支持。
Sock.JS的一大好处在于提供了浏览器兼容性。优先使用原生WebSocket,如果在不支持websocket的浏览器中,会自动降为轮询的方式。
sockjs-client
SockJS模仿WebSockets API,但它不是WebSocket,而是一个SockJS Javascript对象。首先,您需要加载SockJS JavaScript库。例如,你可以把它放在你的HTML head里:
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
sockjs-client建立连接
var sock = new SockJS('https://mydomain.com/my_prefix');
sock.onopen = function () {
console.log('open')
sock.send('test')
}
sock.onmessage = function (e) {
console.log('message', e.data)
sock.close()
}
sock.onclose