WebSocket使用总结

简介

HTTP 协议:通信只能由客户端发起。他可以做成轮询的形式但是浪费资源。HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,TCP连接中可以有多个HTTP连接,但HTTP连接依然是“一次性的”。仍然是客户端主动发起。
WebSocket :服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。建立在 TCP 协议之上,协议标识符是ws(如果加密,则为wss)。

Js客户端

<script type="text/javascript">
    var websocket = null;
    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:8080/websocket");
    }
    else {
        alert('当前浏览器 Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("WebSocket连接发生错误");
    };

    //连接成功建立的回调方法
    websocket.onopen = function () {
        setMessageInnerHTML("WebSocket连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function () {
        setMessageInnerHTML("WebSocket连接关闭");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>

问题

websocket 是长连接,受网络限制比较大,需要处理好重连,比如用户进电梯或电信用户打个电话网断了,这时候就需要重连,如果 ws 一直重连不上,有些较复杂的业务方会不愿意的,是不是还要搞个 http 降级?
所以大部分不重要的业务,使用 ws 不如使用 http 轮训来的简单、实在。
ws 长连接的用户收到消息是个 push 操作,http 轮训用户收消息是 pull 操作,push 都存在单生产推多消费,为广播模型,怎么处理好连接,保障每个消费推且只推一次,很多程序员这个问题不一定能够解决。
pull 就不一样了,消费方想要你就来生产方拉一下,拉几次,消息就准确的送达几次,不存在多消费和连接处理的问题,缺点当然就是消息推送的不及时,优点非常明显,简单易实现。
websocket 当然也不是没有用,企业内部业务系统之间有时候用 http 协议,又想要消息及时推送,上个 mq 太粗暴,用 grpc 这些支持双向流的 rpc 协议太复杂,此时 ws 就非常好使了。
本人在公司做过多个 ws 协议的服务端项目,使用体验非常不错,最头疼的当然就是断线重连的问题。
网页版钉钉的确是 ws, 但不支持在多个页面登录, 登录第二个页面就把之前的给踢掉了。

问题一:WebSocket连接后一分钟自动断开关闭
这是因为websocket长连接有默认的超时时间(1分钟,由proxy_read_timeout决定),就是超过一定的时间没有发送任何消息,连接会自动断开。解决办法就是让浏览器每隔一定时间(要小于超时时间)发送一个心跳。代码如下:
window.setInterval(function(){ //每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
var ping = {"type":"ping"};
ws.send(JSON.stringify(ping));
},5000);

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-WebSo...
    敢梦敢当阅读 9,034评论 0 50
  • 一、内容概览 WebSocket的出现,使得浏览器具备了实时双向通信的能力。本文由浅入深,介绍了WebSocket...
    Calvin李阅读 2,621评论 2 10
  • 经常听到一些人埋怨机遇不等、命运不公,总觉得自己碰不到机遇。每每看到别人的成功,自己总是归结为“运气...
    王丽娜河南商丘彭庄小学阅读 451评论 0 0
  • 一个人面对着无聊的生活 脚踩着泥泞,看着沿途的风景 渐渐我也融入了进去 有一次盯着一滴水慢慢蒸发 后来被阳光宠爱了...
    叁久章阅读 389评论 1 8
  • 匆匆那年,那年匆匆,青春仿佛就像是一场大雨,即使被雨淋感冒,但是也都希望从头再来一次! 青春是青涩的,因为它年轻,...
    糖果小澄阅读 802评论 1 1

友情链接更多精彩内容