跳到主要内容

使用 Websocket 收发消息

WebSocket 是一种网络通信协议,它提供了在单个 TCP 连接上进行全双工通信的能力。与传统的 HTTP 请求-响应模式不同,WebSocket 允许服务器主动向客户端推送数据,实现了真正的双向通信。

主要特点:

  • 全双工通信:客户端和服务器可以同时发送和接收数据
  • 低延迟:建立连接后,数据传输的开销很小
  • 实时性:服务器可以主动推送数据,无需客户端轮询
  • 持久连接:一次握手后保持连接状态,避免重复建立连接

WebSocket 协议以 ws://wss://(安全连接)开头,使用标准的 HTTP 握手过程建立连接,之后升级为 WebSocket 协议进行通信。

本文介绍如何使用云托管(容器型和函数型)实现 Websocket 收发消息。

使用函数型云托管

在本地创建一个目录 websocket-demo,在目录中新建一个 index.js 文件,并编写以下代码:

exports.main = function (event, context) {
console.log({ event, context });
if (context.ws) {
const ws = context.ws;
ws.on("close", (msg) => {
console.log("close: ", msg);
ws.send("bye!");
});
ws.on("message", (msg) => {
console.log("message: ", msg);
ws.send(`echo: ${msg?.data}`);
});
}
};

exports.main.handleUpgrade = async function (upgradeContext) {
console.log(upgradeContext, "upgradeContext");
if (upgradeContext.httpContext.url === "/reject-upgrade") {
return {
allowWebSocket: false,
statusCode: 403,
body: JSON.stringify({ code: "code", message: "message" }),
contentType: "appliaction/json; charset=utf-8",
};
}
return { allowWebSocket: true };
};

这段代码实现了以下功能:

  • main 函数处理 WebSocket 连接后的消息交互:
    • 监听 close 事件,在连接关闭时发送告别消息
    • 监听 message 事件,收到消息时回复当前时间和消息内容
  • handleUpgrade 函数控制 WebSocket 连接的建立:
    • 当访问 /reject-upgrade 时拒绝连接
    • 其他路径允许建立 WebSocket 连接

部署调试

推荐使用 云托管 CLI 进行部署。

安装云托管 CLI 后,进入项目根目录,执行以下命令:

# 登录
tcb login
# 部署函数型云托管实例
tcb cloudrunfuntion deploy

实例部署完成以后,前往 云开发控制台

在左侧导航栏选择【云托管】, 在【服务列表】页面可以找到刚刚部署的实例,点击进入【服务详情】页面,在详情页可以找到默认域名。 将默认域名开头的 https:// 替换为 ws:// 或者 wss:// ,在 Postman 等工具中进行 WebSocket 连接测试。

使用容器型云托管

你可以使用代码示例,示例代码仓库地址

克隆代码仓库后,进入项目根目录,目录结构如下:

├── Dockerfile
├── app
│   └── server.js
└── package.json

其中 app/server.js 是使用 expressexpress-ws 实现的服务,云托管会根据 Dockerfile 来构建容器。

关于容器型云托管的更多信息,可以参考 服务开发说明

部署调试

推荐使用 云托管 CLI 进行部署。

安装云托管 CLI 后,进入项目根目录,执行以下命令:

# 登录
tb login
# 部署容器型云托管实例
tcb cloudrun deploy

实例部署完成以后,前往 云开发控制台

在左侧导航栏选择【云托管】, 在【服务列表】页面可以找到刚刚部署的实例,点击进入【服务详情】页面,在详情页可以找到默认域名。 将默认域名开头的 https:// 替换为 ws:// 或者 wss:// ,在 Postman 等工具中进行 WebSocket 连接测试。