一、使用场景
发布者设置需要发布的公告内容、公告接收用户和发布时间,到达发布时间时及时通知提醒已登录系统用户,使用websocke来实现前端与服务器保持长连接,以便实时过去公告信息。
- WebSocket是一种在单个TCP连接上进行全双工通信的协议。这种协议使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。WebSocket基于TCP传输协议,并且复用HTTP的握手通道,即基于HTTP的"keep-alive"机制,允许在一次TCP连接中传送多个HTTP请求和响应。
- WebSocket的通信过程大致如下:在建立WebSocket连接时,客户端会向服务器发送一个HTTP请求报文,其中包含升级协议的请求头。服务器在接收到该请求后会返回一个HTTP响应报文,其中包含升级协议的响应头。在收到服务器的响应后,客户端和服务器之间的连接就会升级为WebSocket连接,此时客户端和服务器之间的通信就不再需要使用HTTP协议的请求和响应报文,而是直接进行双向数据传输。
- WebSocket协议的特点包括: 较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。
- 更强的实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。
- 保持连接状态:与HTTP不同的是,WebSocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。
- 更好的二进制支持:WebSocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
- 可以支持扩展:WebSocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。
- 与HTTP长连接相比,WebSocket连接在数据传输效率和实时性方面具有明显优势。HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,消息交换效率低。而WebSocket连接在建立后,可以直接进行双向数据传输,无需反复建立连接和发送HTTP请求,从而大大提高了数据传输效率和实时性。
- 总之,WebSocket是一种高效、实时的全双工通信协议,适用于需要实时通信和数据传输的场景。
二、实现过程
- 封装自定义websocket服务
import config from"./config"/** 自定义websocket服务 */exportdefaultclassSocketService{/**
* 单例
*/static instance =nullstaticgetInstance(){if(!this.instance){this.instance =newSocketService()}returnthis.instance
}/** 和服务端连接的socket对象 */
ws =null/** 服务器连接地址 */
wsUrl =null/** 连接用户Id */
userId =null/** 存储回调函数 */
callBackMapping ={}/** 标识是否连接成功 */
connected =false/** 重新连接间隔(ms) */
connectRetryTime =3000/** 重新连接次数 */
connectRetryCount =0/** 定义连接服务器的方法 */connect(_userId){// 连接服务器if(!window.WebSocket){return console.log('您的浏览器不支持WebSocket')}// // =============环境判断===============this.userId = _userId;if(process.env.NODE_ENV=='development'){this.wsUrl = config.development_config.wsUrl + _userId +':'+ Date.now();}elseif(process.env.NODE_ENV=='debug'){this.wsUrl = config.development_config.wsUrl + _userId +':'+ Date.now();}elseif(process.env.NODE_ENV=='production'){this.wsUrl = config.production_config.wsUrl + _userId +':'+ Date.now();}this.ws =newWebSocket(this.wsUrl)// 连接成功的事件this.ws.onopen=()=>{
console.log('Socket连接服务端成功,您的连接地址:'+this.wsUrl);this.connected =true// 重置重新连接的次数this.connectRetryCount =0}// 1.连接服务端失败// 2.当连接成功之后, 服务器关闭的情况this.ws.onclose=()=>{
console.log('连接服务端失败')this.connected =falsethis.connectRetryCount++if(this.connectRetryCount >=10){
console.log('Socket出错,已断开连接');}else{
console.log('Socket出错:第'+this.connectRetryCount +'次重新连接尝试!')this.connect(this.userId);}}}}
- 在用户登录成功后建立连接,App.vue中也要建立连接(用户刷新后要重新连接) login.vue
App.vue
main.js
- 对应通知页面获取数据并以弹框的形式渲染
/** 即时通讯相关参数 */im:{ws:null,messageList:[],message:{},},watch:{'im.message':{handler(newVal, oldVal){if(newVal != oldVal){
console.log('message=>', newVal);this.notVisible =true;setTimeout(()=>{this.notVisible =false;},10000);}},}},created(){// 检测浏览器是否支持Websocketif(typeof WebSocket =='undefined'){this.$alert('系统检测到您的浏览器不支持Websocket通信协议,这将会导致您无法正常进行课堂互动!建议您更换浏览器进行观看!','警告',{confirmButtonText:'知道了',callback:()=>{}});}else{this.im.ws =this.$socket.ws
var retry =setInterval(()=>{if(this.im.ws ==null){this.im.ws =this.$socket.ws
}else{this.initIM();clearInterval(retry)}},1000);}},/** 初始化即时通讯 */initIM(){var _this =this;// 接收消息// console.log(_this.im.ws);
_this.im.ws.onmessage=function(event){var message =JSON.parse(event.data);
_this.im.message = message.data;// console.log(_this.im.message);}// 出现错误
_this.im.ws.onerror=function(error){
_this.$message.error('即时通讯出现错误');
console.log("即时通讯出现错误:", error);};},
本文转载自: https://blog.csdn.net/qq_39071853/article/details/138656398
版权归原作者 Doraemon* 所有, 如有侵权,请联系我们删除。
版权归原作者 Doraemon* 所有, 如有侵权,请联系我们删除。