ajax客户端信息发送,webSocket原理及客户端实战:接收实时消息

需求:

需求实现监听服务端推送过来的消息,效果见下图:

用户某一个动作触发消息发送,在监听接口收到消息并展示出来。

418841ea2d50

接收实时消息.gif

解决方案:

ajax轮询(短轮询)

原理:客户端每隔几秒就发送一次请求,服务器接到请求后马上返回响应信息并关闭连接。

优点:程序编写比较容易。

缺点:请求次数多,请求中有大半是无用,浪费带宽和服务器资源。

long poll (长轮询)

原理:跟ajax轮询差不多,都是采用轮询的方式,区别在于:服务端收到请求后,检测数据是否有新数据,有则立即返回并关闭,无则挂起一直不返回Response直到超时关闭。关闭后客户端再次发起请求建立连接,周而复始。

优点:客户端的请求次数会大量减少

缺点:服务端请求挂起同样会导致资源的浪费

小结:

1.HTTP协议是基于请求/响应模式的,因此只要服务端给了响应,本次HTTP连接就结束了。

2.Ajax轮询与long poll都属于不断发送http请求,然后等待服务器处理,可以看到http协议一个特点,被动性!

webSocket

webSocket是html5一种新的协议,实现了浏览器与服务器之间的全双工通信,能很好的节省服务器资源与带宽,并在服务器端与浏览器端实现实时通行,他建立在TCP之上, 同http一样,通过tcp来传输数据。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

418841ea2d50

image.png

418841ea2d50

image.png

webSocket客户端实例

使用如下的代码可以实现上面图片收到实时消息的效果。

//实时消息

startWebSocket(){

let this_=this;

let wsUrl=urlConfig.wsUrl+localStorage.getItem("access_token");//websocket接口地址

let ws = new WebSocket(wsUrl);

ws.onclose = function () {

this_.reConnect(wsUrl);//重新连接

console.log("连接已关闭 "+new Date());

};

ws.onerror = function () {

this_.reConnect(wsUrl);//重新连接

console.log("连接异常 "+new Date());

};

ws.onopen = function () {

heartCheck.reset().start();//开始心跳检测

console.log("连接成功 "+new Date());

};

ws.onmessage = function (e) {

heartCheck.reset().start();//开始心跳检测

let data = JSON.parse(e.data);

this_.onMessageNotice(data);//获取到数据的回调

};

/*心跳检测:

1.如果当前连接着(onopen或onMessage),就开始心跳检测,即设置定时器一段时间后发送一条数据,发送后再过一段时间关闭连接;

如果在关闭之前,后端正常返回数据(会触发onMessage),会重置心跳检测就一直不会关闭连接。

2.如果当前异常或关闭(onclose,onerror),就重新建立连接;

*/

let heartCheck = {

timeout: 180000, //3分钟发一次心跳

timeoutObj: null,//定时器:延时发送一次心跳

serverTimeoutObj: null,//定时器:延时检测后端是否返回数据,如返回则还连着,如未返回则后端断了

reset: function(){

clearTimeout(this.timeoutObj);

clearTimeout(this.serverTimeoutObj);

return this;

},

start: function(){

let this_ = this;

this.timeoutObj = setTimeout(function(){

ws.send("peng");

console.log("peng");

this_.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了

ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次

}, this_.timeout)

}, this.timeout)

}

};

}

//重新连接websocket

reConnect(url) {

let this_=this;

if(this.lockReconnect) return;

this.setState({

lockReconnect:true//上锁

});

setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多

this_.startWebSocket(url);

this_.setState({

lockReconnect:false//开锁

});

}, 5000);

}

//收到消息的回调

onMessageNotice(data){

notification.info({//antd 中的组件

message: "这是一条消息",

description: "消息描述",

});

//收到消息重新获取消息列表

this.getNewsList();

//播放声音

this.refs.audio.play();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值