使用websocket实现消息推送(下)(代码片段)

ttdevs ttdevs     2022-12-14     590

关键词:

0x00 WebSocket

上一篇使用 Java-WebSocket 写了一套 WebSocket 的Demo,这一篇着重分析下WebSocket 的一些实现细节,更加详细的协议细节可参考 RFC6455

0x01 WebSocket协议

  • WebSocket 协议: 可参考RFC6455
  • 抓包工具:CharlesWireShark
  • 测试代码:参考上一篇Demo

0x02 数据传输

  • 连接和断开

    当 Client 向 Server 发起 ws 连接请求后,会先使用 HTTP 协议建立 TCP 长链接,通过抓包,我们会看到类似这样的信息:

    Request:

    Response:

    这里简单介绍几个关键的Header字段:

    • upgrade:websocket
    • connection:Upgrade
    • sec-websocket-version:13
    • sec-websocket-key:xxxxxx
    • sec-websocket-accept:

    这些字段的信息可参考这里

  • 数据传输

    当 HTTP 连接建立之后,就可以通过这个长链接进行数据传输了。如果你使用 Charles 进行数据抓包的话,可以看到类似下图中这样的聊天内容:

    在同一个 HTTP 请求中,我们看到不断有数据交互,而不是像之前的 HTTP 请求那样,每发送一条数据,都需要发起一次新的请求。

    下面我们来尝试分析一下。这里要用到Wireshark。可能你会为什么换了Wireshark而不用Charles了?原因很简单,Charles给我们呈现的是应用层最终的结果,而传输层的具体的数据包发送接收却不能展示,这个时候就需要借助Wireshark来对TCP数据包进行分析了。

    首先,查询 RFC6455文档,我们得知 ws 协议的数据包格式如下:

    有了这个参考,我们就可以进行数据分析了。下面是我的一次数据收发过程:客户端向服务端发送数据:123456789,然后服务端原样发回,抓包如下:

    Sender:

    Receiver:

    下面我们着重对这两个数据包进行分析。细心的你可能会发现,截图中有四条数据,如果你对TCP的传输有所了解,第二条和第三条是确认报文。

    我们先看下接收到数据。点击数据中的 Data(11bytes) 部分,下方是自动选择了数据部分:8109313233343536373839。(在此之前是TCP报文的Header部分,我们可以忽略)根据 ws 协议,我们将其展开:

    81 09:  10000001 00001001 
    31 32:  00110001 00110010
    33 34:  00110011 00110100
    35 36:  00110101 00110110
    37 38:  00110111 00111000
    39   :  00111001

    0:1,这是最后一帧
    1~3:全为0
    4~7:001,附加数据帧
    8:0,PlayloadData未经过掩码
    9~15:0001001 = 9 < 125,因此数据长度位9
    剩下的:313233343536373839即为数据 123456789

    再来看看发送的数据。点击 Data(15bytes) 部分,下方的数据部分:818911eb9db220d9ae8624ddaa8a28,展开:

    81 89 : 10000001 10001001 
    11 eb : 00010001 11101011
    9d b2 : 10011101 10110010
    20 d9 : 00100000 11011001
    ae 86 : 10101110 10000110
    24 dd : 00100100 11011101
    aa 8a : 10101010 10001010
    28    : 00101000

    0:1,这是最后一帧
    1~3:全为0
    4~7:001,附加数据帧
    8:1,PlayloadData经过掩码,(所有的由客户端发往服务端的帧此数位都被设置成 1。)
    9~15:0001001 = 9 < 125,因此数据长度位9
    11 eb 9d b2:掩码
    20 d9 ae 86 24 dd aa 8a 28:数据
    关于掩码的计算:

  • 连接保持

    除了正常的数据传输之外,Socket编程还有一个重要的组成部分:心跳保持。ws协议中定义了专门的数据包:

    Control frames are identified by opcodes where the most significant bit of the opcode is 1. Currently defined opcodes for control frames include 0x8 (Close), 0x9 (Ping), and 0xA (Pong). Opcodes 0xB-0xF are reserved for further control frames yet to be defined.
    Control frames are used to communicate state about the WebSocket. Control frames can be interjected in the middle of a fragmented message.
    All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented.

  • 其他

    一个协议不可能就这么简单,如果你还想了解更多,可参考RFC6455


参考:

  1. http://www.jianshu.com/p/867274a5e054
  2. http://www.jianshu.com/p/fc09b0899141
  3. https://datatracker.ietf.org/doc/rfc6455/
  4. https://developer.mozilla.org/zh-CN/docs/WebSockets/Writing_WebSocket_servers

使用websocket实现消息推送(心跳)(代码片段)

...跳的事情,这里再做一个补充。先说我的结论:WebSocket协议已经设计了心跳,这个功能可以到达检测链接是否可用心跳是用来检测链接是否可用的,不一定支持携带数据,可要看具体实现如果非要心跳中带上... 查看详情

websocket+rabbitmq实现消息推送系统(代码片段)

...可以引入消息队列RabbitMQ进行流量削峰。向指定用户发送WebSocket消息并处理对方不在线的情况:如果 查看详情

使用websocket实现消息推送(上)(代码片段)

...get方式轮询接入第三方IM系统自己的IM系统基于socket基于websocket第一种方式,最low的,实现简单,但是浪费用户流量;第二种方式,接入简单,功能强大,但是可能需要一定的成本( 查看详情

springboot+netty+websocket实现消息推送(代码片段)

关于NettyNetty是一个利用Java的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。Maven依赖<dependencies> <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency>  <groupId&g 查看详情

springboot+netty+websocket实现消息推送(代码片段)

点击关注公众号,实用技术文章及时了解关于NettyNetty是一个利用Java的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。Maven依赖<dependencies> <!-- https://mvnrepository.com/artifact/io.net... 查看详情

springboot+netty+websocket实现消息推送(代码片段)

点击关注公众号,实用技术文章及时了解关于NettyNetty是一个利用Java的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。Maven依赖<dependencies> <!-- https://mvnrepository.com/artifact/io.net... 查看详情

springboot整合websocket实现实时消息推送(代码片段)

0.开发环境JDK:1.8SpringBoot:2.1.1.RELEASE1.引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>< 查看详情

springboot整合websocket实现实时消息推送(代码片段)

....springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>2.新建WebSocket配置类importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.socket.server... 查看详情

使用websocket给前台推送消息(代码片段)

1.pom配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>1.3.5.RELEASE</version></depen 查看详情

使用websocket给前台推送消息(代码片段)

1.pom配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>1.3.5.RELEASE</version></depen 查看详情

使用websocket给前台推送消息(代码片段)

1.pom配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>1.3.5.RELEASE</version></depen 查看详情

springboot+netty+websocket实现消息推送(代码片段)

springboot和netty,websocket实现消息主动推送注:本文转自:https://mp.weixin.qq.com/s/YWjGdz-4PzOCDfEt4GPoew1.关于NettyNetty是一个利用Java的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。2.Maven依赖<depe... 查看详情

springboot集成websocket,实现后台向前端推送信息(代码片段)

...xff0c;于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,学过计算机网络 查看详情

springboot集成websocket,实现后台向前端推送信息(代码片段)

...xff0c;于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,学过计算机网络 查看详情

springboot+netty+websocket实现消息推送(代码片段)

关于NettyNetty是一个利用Java的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。Maven依赖<dependencies> <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency>  <groupId>... 查看详情

使用websocket实现消息推送

WebSocket上联系客服功能在项目中很难避免,一般有下面三种实现方式: 使用http的get方式轮询接入第三方IM系统自己的IM系统 基于socket基于websocket第一种方式,最low的,实现简单,但是浪费用户流量;第二种方式,接入简... 查看详情

使用websocket实现消息推送

WebSocket上联系客服功能在项目中很难避免,一般有下面三种实现方式:使用http的get方式轮询接入第三方IM系统自己的IM系统基于socket基于websocket第一种方式,最low的,实现简单,但是浪费用户流量;第二种方式,接入简单,功能... 查看详情

后端消息推送-sse协议(代码片段)

...用ajax长轮询,而现在我们有了新的、更优雅的选择——WebSocket和SSE。WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。SSE是Server-SentEvents的简称,是一种服务器端到客户端(浏览器)的单项消息推送。对应的浏... 查看详情