Skip to content

WebSocket

MDN文档WebSocket API - Web API | MDN (mozilla.org)

WebSocket (javascript.info)

HTML5 WebSocket | 菜鸟教程 (runoob.com)

WebSocket简介

WebSocket API 是一种先进的技术,可在用户浏览器和服务器之间开启双向交互式通信会话。利用该 API,可以向服务器发送信息,并接收事件驱动的响应,而无需轮询服务器以获得回复。

备注: 虽然 WebSocket 连接在功能上与标准 Unix 风格的 socket 有些类似,但两者并无关联。

接口

WebSocket

用于连接 WebSocket 服务器的主要接口,之后可以在这个连接上发送和接收数据。

CloseEvent

连接关闭时 WebSocket 对象触发的事件。

MessageEvent

当从服务器获取到消息的时候 WebSocket 对象触发的事件。

WebSocket API的基本使用

WebSocket API:WebSocket - Web API 接口 |MDN的 (mozilla.org)

js
// 创建ws连接
const ws = new WebSocket('ws://localhost:8080/test');
ws.onopen = function() {
    console.log('WebSocket 连接已经建立。');
    ws.send('Hello, server!');
};
ws.onmessage = function(event) {
    console.log('收到服务器消息:', event.data);
};
ws.onerror = function(event) {
    console.error('WebSocket 连接出现错误:', event);
};
ws.onclose = function() {
    console.log('WebSocket 连接已经关闭。');
}

编写 WebSocket 客户端应用

MDN文档:编写 WebSocket 客户端应用 - Web API | MDN (mozilla.org)

编写 WebSocket 服务器

MDN文档:编写 WebSocket 服务器 - Web API | MDN (mozilla.org)

Deno用 JavaScript 编写 WebSocket 服务器

参考:使用 JavaScript 编写 WebSocket 服务器 (Deno) - Web API |MDN的 (mozilla.org)

此示例演示如何使用 Deno 创建 WebSocket API 服务器,并附带一个网页。

Deno 是一个 JavaScript 运行时,它支持 TypeScript 即时编译和缓存。Deno 内置了格式化程序、linter、测试运行器等,还实现了许多 Web API。通过符合 Web 标准,所有特定于 Deno 的 API 都在命名空间下实现。Deno

Deno 网站提供了安装 Deno 的说明。

代码将包含在两个文件中,一个用于服务器,一个用于客户端。

服务端

创建一个main.js文件。此文件将包含简单 HTTP 服务器的代码,该服务器也将为客户端 HTML 提供服务。

js
Deno.serve({
  port: 80,
  handler: async (request) => {
    // If the request is a websocket upgrade,
    // we need to use the Deno.upgradeWebSocket helper
    if (request.headers.get("upgrade") === "websocket") {
      const { socket, response } = Deno.upgradeWebSocket(request);

      socket.onopen = () => {
        console.log("CONNECTED");
      };
      socket.onmessage = (event) => {
        console.log(`RECEIVED: ${event.data}`);
        socket.send("pong");
      };
      socket.onclose = () => console.log("DISCONNECTED");
      socket.onerror = (error) => console.error("ERROR:", error);

      return response;
    } else {
      // If the request is a normal HTTP request,
      // we serve the client HTML file.
      const file = await Deno.open("./index.html", { read: true });
      return new Response(file.readable);
    }
  },
});

Deno.upgradeWebSocket()将连接升级到 WebSocket 连接,这在协议升级机制中有进一步说明。

Deno.serve() 在后台使用 Deno.listen()Deno.serveHttp(),是一个更高级的接口,可以轻松设置 HTTP 服务器。

如果没有它,代码将如下所示。

js
for await (const conn of Deno.listen({ port: 80 })) {
  for await (const { request, respondWith } of Deno.serveHttp(conn)) {
    respondWith(handler(request));
  }
}

客户端

创建一个index.html文件。此文件将包含一个脚本,该脚本将在建立连接后每五秒对服务器执行一次 ping 操作。

html
<!doctype html>
<h2>WebSocket Test</h2>
<p>Sends a ping every five seconds</p>
<div id="output"></div>
<script>
  const wsUri = "ws://127.0.0.1/";
  const output = document.querySelector("#output");
  const websocket = new WebSocket(wsUri);
  let pingInterval;

  function writeToScreen(message) {
    output.insertAdjacentHTML("afterbegin", `<p>${message}</p>`);
  }

  function sendMessage(message) {
    writeToScreen(`SENT: ${message}`);
    websocket.send(message);
  }

  websocket.onopen = (e) => {
    writeToScreen("CONNECTED");
    sendMessage("ping");
    pingInterval = setInterval(() => {
      sendMessage("ping");
    }, 5000);
  };

  websocket.onclose = (e) => {
    writeToScreen("DISCONNECTED");
    clearInterval(pingInterval);
  };

  websocket.onmessage = (e) => {
    writeToScreen(`RECEIVED: ${e.data}`);
  };

  websocket.onerror = (e) => {
    writeToScreen(`ERROR: ${e.data}`);
  };
</script>

运行代码

使用这两个文件,使用 Deno 运行应用程序。

bash
deno run --allow-net=0.0.0.0:80 --allow-read=./index.html main.js

Deno 要求我们为可以在主机上访问的内容提供明确的权限。

  • --allow-net=0.0.0.0:80允许应用在端口 80 上附加到 localhost
  • --allow-read=./index.html允许访问客户端的 HTML 文件

在线工具

websocket在线测试 (websocket-test.com)

工具库

  • AsyncAPI:用于描述基于 WebSocket 等协议的事件驱动架构的规范。可以使用它来描述基于 WebSocket 的 API,就像使用 OpenAPI 规范描述 REST API 一样。了解为什么要考虑将 AsyncAPI 与 WebSocket 结合使用如何使用
  • HumbleNet:一个在浏览器中工作的跨平台网络库。它由 WebSocket 和 WebRTC 的 C 语言封装器组成,可抽象出跨浏览器的差异,便于为游戏和其他应用程序创建多用户网络功能。
  • µWebSockets:由 C++11Node.js 实现的高度可扩展的 WebSocket 服务器和客户端。
  • Socket.IO:基于长轮询和 WebSocket 的 Node.js 第三方传输协议。
  • SocketCluster:适用于 Node.js 的 pub/sub WebSocket 框架,注重可扩展性。
  • WebSocket-Node:用 Node.js 实现的 WebSocket 服务器 API。
  • Total.js:用 Node.js 实现的 Web 应用程序框架(例如:WebSocket 聊天)。
  • Faye:用于 Node.js 服务器和客户端的 WebSocket(双向连接)和 EventSource(单向连接)。
  • SignalR:当 WebSocket 可用时,SignalR 将在覆盖范围内使用 WebSocket;当 WebSocket 不可用时,SignalR 将优雅地回退到其他技术,而应用程序代码保持不变。
  • Caddy:能够将任意命令(stdin/stdout)代理为 websocket 的 web 服务器。
  • ws:流行的 WebSocket 客户端和服务器 Node.js 库。
  • jsonrpc-bidirectional:异步 RPC,在一个连接上,服务器和客户端可以同时导出函数(客户端可以调用服务器,服务器也可以调用客户端)。
  • cowboy:Cowboy 是一款小型、快速、现代的 Erlang/OTP HTTP 服务器,支持 WebSocket。
  • ZeroMQ:ZeroMQ 是一个可嵌入的网络库,可通过进程内、IPC、TCP、UDP、TIPC、组播和 WebSocket 传输消息。
  • WebSocket King:帮助开发、测试和使用 WebSocket 服务器的客户端工具。
  • PHP WebSocket Server:用 PHP 编写的服务器,用于处理通过 websocket wss:// 或 ws:// 以及通过 ssl:// 和 tcp:// 的普通套接字进行的连接。
  • Channels:增加了对 WebSocket(以及其他需要长时间运行异步连接的协议)的支持的 Django 库。
  • Channels:在 Elixir Phoenix 框架中使用 WebSocket 进行可扩展的实时通信。
  • LiveView:在 Elixir Phoenix 框架中通过 WebSocket 实现实时交互式网络体验。
  • Flask-SocketIO:让 Flask 应用程序可以在客户端和服务器之间进行低延迟的双向通信。
  • Gorilla WebSocket:Gorilla WebSocket 是 WebSocket 协议的 Go 实现。

规范

Specification
WebSockets Standard # the-websocket-interface

教程

使用ws - 廖雪峰的官方网站 (liaoxuefeng.com)

WebSocket协议:5分钟从入门到精通 - 程序猿小卡 - 博客园 (cnblogs.com)

其他教程:

基于WebRtc和WebSocket实现视频聊天 - 掘金 (juejin.cn)

websocket封装:赶快收藏!全网最佳websocket封装:完美支持断网重连、自动心跳! - 掘金 (juejin.cn)

Released under the MIT License.