zoukankan      html  css  js  c++  java
  • websocket协议

    1. websocket协议

    WebSocket协议提供一个供TCP连接进行双向通讯的机制,基于TCP传输协议,并复用HTTP的握手通道。

    2. 长连接,轮询,长轮询,websocket的前世今生

    我们可能经常会听到长连接,轮询,长轮询,websocket这几个概念,并且可能对他们的区别有些模糊

    2.1 websocket与http的关系

    他和http的协议就如同下面的关系,有共用的部分,但不是一个东西。Websocket其实是一个新协议,跟HTTP协议不同,为了兼容现有浏览器的握手规范,借用了HTTP的协议来完成一部分握手,所以他们在握手阶段是基本一样的。

    2.2 长连接

    在我们的认识下,http协议中,Request = Response,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。

    每一个请求开始后都会经历握手的过程,握手结束后开始传输数据,显然这样的效率不高,所有聪明的开发者们想到了,可不可以在一次握手结束后,发送多个请求,并接收多个请求,keep-alive应运而生。HTTP有1.1和1.0之说,http1.1一个比较重要的方面就是增加了keep-alive,HTTP1.1的连接默认使用持续连接。

    2.3 轮询

    轮询 的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

    场景再现:

    客户端:.有没有新信息(Request)

    服务端:没有.(Response)

    客户端:..有没有新信息(Request)

    服务端:没有..(Response)

    客户端:...有没有新信息(Request)

    服务端:有消息,告诉你,今天要下雨...(Response)

    客户端:...有没有新消息(Request)

    服务端:没有..(Response)

    。。。。。。

    ---- loop

    很明显这样的方式,轮询就会造成对网络和通信双方的资源的浪费,且非实时

    2.4 长轮询

    长轮询其实原理跟轮询差不多,都是采用轮询的方式,不过采取的是阻塞模型,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

    场景再现

    客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)

    服务端:额。。 等待到有消息的时候。。来 给你(Response)

    客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)

    。。。。

    ----loop

    相比于轮询,这种方式网络带宽占用少了,但是本质上都体现了服务器的被动型,只有请求过来,才能回答,不能主动与客户端沟通。

    2.5 websocket

    相对于http协议,websocket协议在握手阶段结束,建立起连接后,双方通讯会一直保持,并且客户端和服务端任何一方都可以主动向对方发送新消息,并且另一端通过监听onXXX事件可以收到这个信息。

    3. websocket的详细介绍

    它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。WebSocket 允许服务器端与客户端进行全双工(full-duplex)的通信。

    其他特点包括:

    (1)建立在 TCP 协议之上,服务器端的实现比较容易。

    (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

    (3)数据格式比较轻量,性能开销小,通信高效。

    (4)可以发送文本,也可以发送二进制数据。

    (5)没有同源限制,客户端可以与任意服务器通信,完全可以取代 Ajax。

    (6)协议标识符是ws(如果加密,则为wss,对应 HTTPS 协议),服务器网址就是 URL。

    WS协议有两部分组成:握手和数据传输。

    3.1 websocket握手阶段

    这就是我们所了解的TCP三次握手,重温下这个经典的瞬间。。。

    下面是我截取的一个websocket请求

    通过上图可以看到和http的请求响应很像,

    请求头中,这里需要注意几个域,有一个 HTTP 头是Upgrade。HTTP1.1 协议规定,Upgrade表示将通信协议从HTTP/1.1转向该字段指定的协议。Connection字段表示浏览器通知服务器,如果可以的话,就升级到 WebSocket 协议。Origin字段用于提供请求发出的域名,供服务器验证是否许可的范围内(服务器也可以不验证)。Sec-WebSocket-Key则是用于握手协议的密钥,是 Base64 编码的16字节随机字符串。

    响应头中,服务器同样用Connection字段通知浏览器,需要改变协议。Sec-WebSocket-Accept字段是服务器在浏览器提供的Sec-WebSocket-Key字符串后面,添加“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”字符串,然后再取 SHA-1 的哈希值。浏览器将对这个值进行验证,以证明确实是目标服务器回应了 WebSocket 请求。

    3.2 数据传输

    看一下客户端的简单实例

    var ws = new WebSocket('wss://echo.websocket.org');
    
    ws.onopen = function(evt) {
      console.log('Connection open ...');
      ws.send('Hello WebSockets!');
    };
    
    ws.onmessage = function(evt) {
      console.log('Received Message: ' + evt.data);
      ws.close();
    };
    
    ws.onclose = function(evt) {
      console.log('Connection closed.');
    };
    

    代码比较简单,也容易理解,就是几个回调函数。同样服务端也要实现监听事件,这样双方就可以通讯了。需要注意的是,websocket不仅可以发送text类型数据,还可以发送二进制数据,如果有需要,on message 的时候可以进行下判断。

    参考资料

    https://www.zhihu.com/question/20215561
    http://javascript.ruanyifeng.com/htmlapi/websocket.html#toc0

  • 相关阅读:
    Non-Photorealistic Rendering using OpenCV ( Python, C++ )
    Tensorflow Eager execution and interface
    Linear and Logistic Regression in TensorFlow
    TensorFlow Ops
    Introduction to TensorFlow
    Java Syntax Specification
    java方法的虚分派和方法表
    λ演算
    活性变量分析
    java垃圾回收机制
  • 原文地址:https://www.cnblogs.com/redirect/p/10066714.html
Copyright © 2011-2022 走看看