当前位置: 首页 > 知识库问答 >
问题:

javascript - websocket怎么实现单聊功能?

苏鹏鹍
2023-08-09

如题,怎么实现单聊功能并给指定连接设备发送消息?

共有3个答案

赵奕
2023-08-09

单聊可以在 socket 过程中加个身份认证,我这里用随机 id ,正常可以直接用用户名或者 uid ,只要能保证唯一就行

当然正常使用的 id 肯定是 持久化 的,不会像示例代码中只是用变量缓存,除非是临时的一次性聊天需求

服务端:

const WebSocketServer = require('websocket').server;const http = require('http');// 创建HTTP服务器const server = http.createServer((req, res) => {});// 创建WebSocket服务器const wsServer = new WebSocketServer({    httpServer: server});// 存储连接的客户端(用 set 也行)const clients = {};// 处理客户端连接请求wsServer.on('request', (req) => {    const connection = req.accept(null, req.origin);        // 生成客户端ID(最好保证唯一性,此处教程简单演示)    const clientId = Math.random().toString(36).substr(2, 9);        // 存储客户端连接    clients[clientId] = connection;        // 发送连接成功消息给客户端    connection.sendUTF(JSON.stringify({ type: 'connect', clientId }));        // 处理收到的消息    connection.on('message', (msg) => {        if (msg.type === 'utf8') {            const data = JSON.parse(msg.utf8Data);                        if (data.type === 'private_message') {                const { to, message } = data;                                // 查找要发送给的客户端                const targetClient = clients[to];                                if (targetClient) {                    // 发送私聊消息给目标客户端                    targetClient.sendUTF(JSON.stringify({ type: 'private_message', from: clientId, message }));                } else {                    // 目标客户端不存在,发送错误消息给发送方                    connection.sendUTF(JSON.stringify({ type: 'error', message: '目标用户不存在' }));                }            }        }    });        // 处理客户端关闭连接    connection.on('close', () => {        // 删除已关闭的连接        delete clients[clientId];    });});// 启动服务器server.listen(8080, () => {    console.log('WebSocket服务器已启动');});

客户端1:

<!DOCTYPE html><html>    <head>        <title>客户端1</title>    </head>    <body>        <h1>客户端1</h1>        <div id="messages"></div>        <form id="sendForm">            <input type="text" id="toInput" placeholder="目标客户端ID">            <input type="text" id="messageInput" placeholder="消息内容">            <button type="submit">发送</button>        </form>        <script>            const ws = new WebSocket('ws://localhost:8080');            ws.onopen = () => {                console.log('已连接到服务器');            };            ws.onmessage = (event) => {                const data = JSON.parse(event.data);                if (data.type === 'connect') {                    console.log('连接成功,我的ID是:', data.clientId);                } else if (data.type === 'private_message') {                    console.log('收到私聊消息:', data.from, '发来的', data.message);                    displayMessage(data.from, data.message);                }            };            document.getElementById('sendForm').addEventListener('submit', (e) => {                e.preventDefault();                const to = document.getElementById('toInput').value;                const message = document.getElementById('messageInput').value;                const data = {                    type: 'private_message',                    to,                    message                };                ws.send(JSON.stringify(data));                document.getElementById('toInput').value = '';                document.getElementById('messageInput').value = '';            });            function displayMessage(from, message) {                const div = document.createElement('div');                div.textContent = `${from}: ${message}`;                document.getElementById('messages').appendChild(div);            }        </script>    </body></html>

客户端2:

<!DOCTYPE html><html>    <head>        <title>客户端2</title>    </head>    <body>        <h1>客户端2</h1>        <div id="messages"></div>        <form id="sendForm">            <input type="text" id="toInput" placeholder="目标客户端ID">            <input type="text" id="messageInput" placeholder="消息内容">            <button type="submit">发送</button>        </form>        <script>            const ws = new WebSocket('ws://localhost:8080');            ws.onopen = () => {                console.log('已连接到服务器');            };            ws.onmessage = (event) => {                const data = JSON.parse(event.data);                if (data.type === 'connect') {                    console.log('连接成功,我的ID是:', data.clientId);                } else if (data.type === 'private_message') {                    console.log('收到私聊消息:', data.from, '发来的', data.message);                    displayMessage(data.from, data.message);                }            };            document.getElementById('sendForm').addEventListener('submit', (e) => {                e.preventDefault();                const to = document.getElementById('toInput').value;                const message = document.getElementById('messageInput').value;                const data = {                    type: 'private_message',                    to,                    message                };                ws.send(JSON.stringify(data));                document.getElementById('toInput').value = '';                document.getElementById('messageInput').value = '';            });            function displayMessage(from, message) {                const div = document.createElement('div');                div.textContent = `${from}: ${message}`;                document.getElementById('messages').appendChild(div);            }        </script>    </body></html>

演示效果

客户端1


客户端2


但是现在还有一个问题,就是不能看到自己发送的消息,这个可以通过每次发送消息也携带自己的 id 来实现(代码我就没改了,题主有需求可以自行更新)
实现看到自己发送的消息

孔运珧
2023-08-09

给当前的 websocket 会话记录一个唯一的 id,本端发 websocket 消息的时候指定对端会话的 id 就行了,用服务端来做转发

庄萧迟
2023-08-09

前端发送消息时指定 接收方用户ID,服务端收到消息后将消息持久化(存储至数据库等),若接收方用户 在线 则将消息发送即可,以下为 nodejs 实现的简单示例:

const WebSocket = require("ws");const server = new WebSocket.Server({ port: 8080 });const clients = new Map();server.on("connection", (socket) => {  socket.on("message", (msg) => {    const message = JSON.parse(msg);    switch (message.type) {      case "online": {        clients.set(message.userId, socket);        console.log(`用户(${message.userId})已上线`);        break;      }      case "message": {        const record = {          type: "message",          fromUserId: message.fromUserId,          toUserId: message.toUserId,          text: message.text        };        // 存储消息至数据库 collection.insertOne(record);        const target = clients.get(message.toUserId);        if (target != null) {          // 若目标用户在线,则发送消息至目标用户          target.send(JSON.stringify(record));        }        break;      }    }  });  socket.on("close", () => {    for (const [key, value] of clients.entries()) {      if (value === socket) {        clients.delete(key);        console.log(`用户(${key})已下线`);        break;      }    }  });});
 类似资料:
  • 本文向大家介绍微信小程序websocket实现聊天功能,包括了微信小程序websocket实现聊天功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了微信小程序websocket实现聊天功能的具体代码,供大家参考,具体内容如下 效果图: chat.js chat.wxml chat.wxss github前后端都有地址:wx-chat  为大家推荐现在关注度比较高的微信小程序教程一篇

  • 本文向大家介绍微信小程序websocket实现即时聊天功能,包括了微信小程序websocket实现即时聊天功能的使用技巧和注意事项,需要的朋友参考一下 今天给大家分享一下本人做小程序使用websocket的一点小经验,希望对大家有所帮助。 使用之前肯定首先要了解一下websocket是什么,简单来讲websocket就是客户端与服务器之间专门建立的一条特殊通道,请求只需要请求一次,而且还可以从通道

  • 在移动端怎么实现pdf打印功能 尝试使用window.print() ios手机浏览器支持window.print,但是在企业微信里面不支持 安卓手机h5不支持window.print 有没有移动端h5实现打印功能的 还是说必须原生app来实现打印。

  • 本文向大家介绍Android使用Websocket实现聊天室,包括了Android使用Websocket实现聊天室的使用技巧和注意事项,需要的朋友参考一下 最近的项目中要实现一个聊天的功能,类似于斗鱼TV的聊天室功能,与服务器端人商量后决定用WebSocket来做,但是在这之前我只知道Socket但是听都没有听过WebSocket,但是查看了相关的材料以后发现实现一个聊天室其实是很简单的!下面我们

  • 1.项目使用window.open下载时,并没有携带token,容易被盗链下载,况且使用这个api,后端没有办法校验token,把token拼接在url后面还是一样的,前端直接去对应地址取文件,后端并没办法取到token; 2.使用正常的接口下载,blob格式的,由于文件比较大,经常会出现数百M或者上G的大小,在下载过程中,如果页面被刷新也会失败;好像还不能用分片下载,因为文件可能是安装包,有可能

  • 本文向大家介绍JavaScript实现表单验证功能,包括了JavaScript实现表单验证功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了JavaScript实现表单验证功能的具体代码,供大家参考,具体内容如下 以下是JavaScript的表单验证功能,可根据JS代码编写出你想要的HTML和CSS的代码。 关于正则表达式的使用,以及常用的正则表达式,笔者目前还在整理中,后期整理完