Skip to content

webSocket 使用

vue使用:

vue
<template>
  <button @click="send('你好,测试!')">发送消息</button>
  <button @click="but">点击连接</button>
</template>

<script setup>
import { ref } from "vue";
const ws = ref(null);

function but() {
  // 连接 WebSocket 服务器
  ws.value = new WebSocket("ws://localhost:3000/ws");

  // 连接成功时触发
  ws.value.onopen = () => {
    console.log("已连接到服务器");
    ws.value.send("Hello, Server!"); // 向服务器发送消息
  };

  // 收到服务器消息时触发
  ws.value.onmessage = (event) => {
    console.log("收到服务器消息:", event.data);
  };

  // 连接关闭时触发
  ws.value.onclose = () => {
    console.log("连接已关闭");
  };

  // 连接出错时触发
  ws.value.onerror = (err) => {
    console.error("连接错误:", err);
  };
}

function send(message) {
  ws.value.send(message);
}
</script>

node使用:

  • 安装express-ws
js
npm install express-ws
  • 使用
js
const express = require('express');
const expressWs = require('express-ws');

// 创建 Express 应用
const app = express();

// 将 WebSocket 功能绑定到 Express 应用
expressWs(app);

// WebSocket 连接的路由(客户端需通过 ws://localhost:3000/ws 连接)
app.ws('/ws', (ws, req) => {
    // 当客户端发送消息时触发
    ws.on('message', (msg) => {
        console.log('收到客户端消息:', msg.toString());

        // 向客户端发送消息
        ws.send(`服务器已收到:${msg.toString()}`);
    });

    // 当连接关闭时触发
    ws.on('close', () => {
        console.log('客户端断开连接');
    });

    // 当连接出错时触发
    ws.on('error', (err) => {
        console.error('WebSocket 错误:', err);
    });
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
    console.log(`WebSocket 地址:ws://localhost:${PORT}/ws`);
});

express-ws全局效果

js
const express = require('express');
const expressWs = require('express-ws');

const app = express();
const wsInstance = expressWs(app);
const wss = wsInstance.getWss(); // 获取 WebSocket 服务器实例(获取所有连接的客户端等等全局的用途)

// 向所有在线客户端广播消息
wss.clients.forEach(client => {
  if (client.readyState === WebSocket.OPEN) { // 确保连接处于打开状态
    client.send('这是一条广播消息');
  }
});

console.log(`当前在线连接数:${wss.clients.size}`);

// 关闭所有连接
wss.clients.forEach(client => {
  client.close(1001, '服务器即将重启'); // 1001 表示客户端离开
});

// 当有新客户端连接时触发
wss.on('connection', (ws) => {
  console.log('新客户端连接,当前在线数:', wss.clients.size);
});

一对一聊天

js
const express = require('express');
const expressWs = require('express-ws');

const app = express();
const wsInstance = expressWs(app);
const wss = wsInstance.getWss(); // 获取 WebSocket 服务器实例(获取所有连接的客户端等等全局的用途)

// 存储用户连接的映射表:userId → WebSocket 实例
const userConnections = new Map();

// WebSocket 路由(客户端需通过 ws://localhost:3000/chat?userId=xxx 连接)
app.ws('/chat', (ws, req) => {
  // 1. 获取当前连接的用户 ID(从查询参数中提取)
  const userId = req.query.userId;
  if (!userId) {
    ws.close(1008, '缺少用户 ID'); // 关闭连接并提示错误
    return;
  }

  // 2. 存储用户与连接的映射
  userConnections.set(userId, ws);
  console.log(`用户 ${userId} 已连接,当前在线用户:`, Array.from(userConnections.keys()));

  // 3. 监听客户端发送的消息
  ws.on('message', (msg) => {
    try {
      // 解析消息(约定格式:{ to: 目标用户ID, content: 消息内容 })
      const message = JSON.parse(msg.toString());
      const { to: targetUserId, content } = message;

      // 检查目标用户是否在线
      const targetWs = userConnections.get(targetUserId);
      if (targetWs && targetWs.readyState === WebSocket.OPEN) {
        // 向目标用户发送消息(附加发送者 ID)
        targetWs.send(JSON.stringify({
          from: userId,
          content,
          time: new Date().toLocaleTimeString()
        }));
      } else {
        // 目标用户不在线,通知发送者
        ws.send(JSON.stringify({
          error: `用户 ${targetUserId} 不在线或已断开连接`
        }));
      }
    } catch (err) {
      // 消息格式错误
      ws.send(JSON.stringify({ error: '消息格式错误,请使用 { to: xxx, content: xxx }' }));
    }
  });

  // 4. 监听连接关闭,移除映射
  ws.on('close', () => {
    userConnections.delete(userId);
    console.log(`用户 ${userId} 已断开,当前在线用户:`, Array.from(userConnections.keys()));
  });

  // 5. 错误处理
  ws.on('error', (err) => {
    console.error(`用户 ${userId} 连接错误:`, err);
  });
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
  console.log(`WebSocket 连接地址:ws://localhost:${PORT}/chat?userId=xxx`);
});

uniapp连接websocket

vue
<template>
	<view>
		<text>WebSocket Demo</text>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				socketTask: null
			}
		},
		onLoad() {
			this.connectWebSocket()
		},
		onUnload() {
			if (this.socketTask) {
				this.socketTask.close({
					success: () => {
						console.log('关闭WebSocket连接成功')
					}
				})
			}
		},
		methods: {
			connectWebSocket() {
				// 假设我们有一个token,通常是从登录接口获取的
				const token = 'your-token-here'
				
				// 创建WebSocket连接,注意:小程序中需要使用socketTask
				this.socketTask = uni.connectSocket({
					url: `ws://localhost:3000/ws?token=${token}`, // 后端WebSocket地址,携带token
					success: () => {
						console.log('WebSocket连接创建成功')
					},
					fail: (err) => {
						console.error('WebSocket连接创建失败', err)
					}
				})
				
				// 监听WebSocket连接打开事件
				this.socketTask.onOpen(() => {
					console.log('WebSocket连接已打开')
					// 发送一条测试消息
					this.socketTask.send({
						data: 'Hello, Server!',
						success: () => {
							console.log('消息发送成功')
						}
					})
				})
				
				// 监听WebSocket接收消息事件
				this.socketTask.onMessage((res) => {
					console.log('收到服务器内容:', res.data)
				})
				
				// 监听WebSocket错误事件
				this.socketTask.onError((err) => {
					console.error('WebSocket连接发生错误', err)
				})
				
				// 监听WebSocket关闭事件
				this.socketTask.onClose(() => {
					console.log('WebSocket连接已关闭')
				})
			}
		}
	}
</script>