java - 了解服务器端的 websockets

标签 java websocket

我在理解 websocket 通信方面有一些问题。 AFAIU,在客户端,它是这样工作的:

  1. 从客户端,使用“new WebSocket('ws://blahblah')”创建一个新的套接字处理程序
  2. 然后使用 onOpen() 方法知道我们已连接到 WS 服务器
  3. 使用 onMessage() 方法,知道已从 WS 服务器接收到消息
  4. OnClose() 方法指示套接字连接已关闭

所以从客户的角度来看,这很清楚。 但是从服务器的角度来看,流程是如何进行的(如上客户端),websocket 服务器进程的确切含义是什么,我们所说的通信发生在 TCP 上的确切时间是什么,以及我们如何检查它(如果问题是,我很抱歉非常基本)

谁能解释一下。 提前致谢

最佳答案

在服务器端,它实际上取决于 websockets 库的实现、语言和 API,或者您使用的自己的实现。

此描述实际上仅适用于 WebSockets 的 RAW 实现,并不基于使用任何库来处理 WebSockets 协议(protocol)。 库,如 jWebSockets (Java)、SignalR、socket.io 和其他库将有完全不同的进程来使用 WebSockets。

如果我们谈论原始套接字上的原始实现,那么过程就是这样:

  1. 创建服务器端 TCP 套接字,绑定(bind)到特定端口并监听它,然后进入接受状态。接受可以是阻塞的或非阻塞的。我使用.Net,并进行了异步接受,这样每次连接到服务器时它都会触发方法。 1b.客户端通过JS调用:new WebSocket(...);
  2. 接受新套接字后,就得开始接收数据了。 TCP 协议(protocol)是基于流的,而不是基于消息的。
  3. WebSockets 协议(protocol)要求在您可以通信之前完成 WebSockets 的 HTTP 握手。因此,在接受新套接字后,您会立即开始接收数据,首先您将收到握手数据 - 几行文本。
  4. 继续握手过程。这意味着读取握手数据,并在服务器端生成响应握手数据并将其发送到 WebSocket。 4b.如果握手数据将被客户端(浏览器)验证和验证,你将得到回调“onopen”,否则你可能会在它之后得到“onerror”和“onclose”。
  5. 握手完成后,就可以收发消息了。消息是基于 WebSockets 协议(protocol)的数据帧(非原始)。 WebSockets 是基于 MESSAGE 的协议(protocol)。因此,在对数据进行逻辑处理之前,必须确保读取了特定数量的消息数据。
  6. 为了在服务器端接收数据,如果您使用自己的实现,则必须实现从 TCP 套接字流中读取数据。为此,您将始终只想读取 2 个字节,如果会有一些(2 个字节)-这是 header 数据,根据协议(protocol)数据帧规范对其进行解码,并继续读取其余数据以查明是否有屏蔽然后读取屏蔽字节和长度。这一切都在标题中。但标题的长度可能略有不同。这就是为什么您必须先读取 2 个字节,然后再读取一些字节。获得长度后,您必须从 TCP 套接字流中准确读取该字节长度。全部读取后,实际数据被去除掩码(如果启用了掩码,根据我的经验,它始终处于启用状态),之后,您可以让套接字从头开始读取一些其他数据。在阅读完当前邮件之前不要开始阅读新邮件。
  7. 消息被读取和去除掩码后,您将获得原始数据,在大多数情况下,它只是您使用“socket.send("..."); 从客户端发送的字符串。
  8. 要发送数据,你必须先获取原始字符串数据,然后使用UTF8编码获取字符串字节,然后用数据帧覆盖它,所以它与读取相反,唯一不同的是你不应该做掩码。因此,从服务器到客户端的数据不会被屏蔽。
  9. 制作二进制文件并发送后,如果一切正常,您可能会在客户端收到包含您发送的数据的“onmessage”。

客户端永远不会收到部分数据,或无序数据。它将始终按照您发送的顺序接收数据包,并且始终按照您发送的顺序接收数据包。 服务器可能部分地基于低级 TCP 层进程接收数据。但总是会收到订单。

此协议(protocol)是可靠且有序的。

最流行的 WebSockets 协议(protocol)规范 RFC 6455 ,请记住,iOS 使用另一个规范,它们可能不交叉兼容,这意味着您需要专门为不同的协议(protocol)实现创建另一个握手功能和数据框架。

关于java - 了解服务器端的 websockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10649336/

相关文章:

java - 根元素在 Spring Batch 中被多次写入

java - 带或不带显式变量的多方法调用

Java 正则表达式所有格量词

java - 在特定 JTable 单元格中显示图标

java - 欧拉计划 #4 : Java

nginx - 如何在Kubernetes中为多个服务设置粘性 session ?

websocket - 哪个版本的 SignalR 支持 WebSockets?

javascript - 未使用 angularjs 触发 WebSocket 回调

java - 服务器外部的 Web Socket java 客户端

java - 在 Java 注释处理器中获取环境变量