TypeScript 上的 WebSocket:构建实时应用
现代 Web 应用需要客户端与服务器之间进行即时数据交换。WebSocket 协议能够提供持久化的双向连接,使其成为构建聊天系统、通知系统、在线游戏以及其他实时服务的理想选择。本文将深入探讨如何在 TypeScript 中使用 WebSocket —— 从服务器搭建到客户端实现。
什么是 WebSocket,为什么需要它?
WebSocket 是一种通信协议,它通过单一 TCP 连接提供全双工通信通道。与传统的 HTTP(客户端发送请求并等待响应)不同,WebSocket 允许服务器主动向客户端发送数据。
WebSocket 的主要优势:
- 持久连接 —— 无需为每次请求建立新连接
- 低延迟 —— 数据即时传输,无需 HTTP 头部的额外开销
- 双向通信 —— 服务器无需客户端请求即可发送数据
- 高效率 —— 与轮询方案相比,流量更少
WebSocket 广泛应用于金融应用(股票行情)、社交网络(实时点赞、评论)、多人在线游戏、监控系统以及物联网领域。
在 TypeScript 上搭建 WebSocket 服务器
为了创建服务器,我们将使用流行的库 ws。通过 npm 安装它:
npm init -y
npm install ws
npm install -D typescript @types/ws @types/node
npx tsc --init
创建一个文件 server.ts:
import { WebSocketServer, WebSocket } from 'ws';
const PORT = 8080;
const wss = new WebSocketServer({ port: PORT });
interface CustomMessage {
type: string;
payload: any;
}
wss.on('connection', (ws: WebSocket) => {
console.log('新客户端已连接');
// 发送欢迎消息
const welcomeMessage: CustomMessage = {
type: 'welcome',
payload: { message: '欢迎连接到服务器!' }
};
ws.send(JSON.stringify(welcomeMessage));
// 处理接收到的消息
ws.on('message', (data: Buffer) => {
try {
const message: CustomMessage = JSON.parse(data.toString());
switch (message.type) {
case 'chat':
// 向所有连接的客户端广播消息
broadcast(message, ws);
break;
case 'ping':
ws.send(JSON.stringify({ type: 'pong', payload: {} }));
break;
default:
console.log('未知消息类型:', message.type);
}
} catch (error) {
console.error('处理消息时出错:', error);
}
});
ws.on('close', () => {
console.log('客户端已断开连接');
});
ws.on('error', (error: Error) => {
console.error('WebSocket 错误:', error);
});
});
function broadcast(message: CustomMessage, sender: WebSocket) {
wss.clients.forEach((client) => {
if (client !== sender && client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(message));
}
});
}
console.log(`WebSocket 服务器已启动,地址为 ws://localhost:${PORT}`);
使用命令 npx ts-node server.ts 启动服务器。服务器将在 8080 端口监听并处理传入的连接。
在 TypeScript 上创建 WebSocket 客户端
客户端部分既可以在浏览器中实现,也可以在 Node.js 中实现。让我们来看看这两种方案。
浏览器客户端
创建一个文件 client.ts 用于 Web 应用:
class WebSocketClient {
private socket: WebSocket;
private url: string;
constructor(url: string) {
this.url = url;
this.socket = new WebSocke