游侠网云服务,免实名免备案服务器 游侠云域名,免实名免备案域名

统一声明:

1.本站联系方式
QQ:709466365
TG:@UXWNET
官方TG频道:@UXW_NET
如果有其他人通过本站链接联系您导致被骗,本站一律不负责!

2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET
3.免实名域名注册购买- 游侠云域名
4.免实名国外服务器购买- 游侠网云服务
Websocket聊天室代码怎么写?保姆级完整实战教程教你从0到1

先搞懂Websocket到底是啥,不然代码写了也白瞎

你可能会问:“不就是个通信协议吗?用HTTP不行吗?”我告诉你,之前我也是这么想的,直到踩了大雷才明白——Websocket和HTTP的区别,根本就是“打电话”和“发消息”的区别。我给你做了个对比表,一眼就能看明白:

特性 HTTP Websocket
连接方式 客户端主动请求,服务器响应后断开 客户端与服务器建立长连接,一直保持
通信方向 单向(客户端问→服务器答) 双向(客户端和服务器都能主动发消息)
延迟 高(需等待请求-响应周期) 低(连接保持,消息即时发送)
资源占用 高(频繁建立连接) 低(一个连接复用到底)

MDN Web Docs( Mozilla 开发的权威Web文档)明确说:“Websocket 是为了解决实时Web应用的需求而设计的,比如聊天室、实时游戏这类需要双向快速通信的场景。”我室友的美食社群,正好需要用户实时分享“哪家店出了新品”“排队人多不多”,用Websocket简直太合适了——消息发出去0.1秒内所有人都能收到,比微信还快。

你可能又会问:“那Websocket难学吗?”我告诉你,一点都不难,只要你会写点JS,就能跟着做。我去年学的时候,也就花了半天时间,从安装依赖到写出能跑的代码,关键是得把“长连接”“双向通信”这两个概念吃透。

手把手写Websocket聊天室代码,每一步都给你扒开讲

我用Node.js(后端)+ 原生JS(前端)来写,因为这俩是最常用、资料最多的组合,你学了之后换成其他语言(比如Python的websockets库、Java的Spring WebSocket)也能举一反三。

第一步:搭后端Websocket服务器(Node.js + ws库)

你得装Node.js(官网下载就行,选LTS版本),然后新建个文件夹,比如叫“websocket-chat”,打开终端输npm init -y初始化项目,再装Websocket的依赖:npm install ws——这个ws库是Node.js生态里最火的Websocket库,Node.js官方文档都推荐用它。

然后新建个server.js文件,写后端代码。我给你贴代码,每一行都给你解释:

// 引入ws库,创建WebSocket服务器

const WebSocket = require('ws');

// 创建服务器实例,监听3000端口

const wss = new WebSocket.Server({ port: 3000 });

// 存储所有连接的客户端(后面广播消息要用)

const clients = new Set();

// 当有客户端连接时触发connection事件

wss.on('connection', (ws) => {

// 把新连接的客户端加入clients集合

clients.add(ws);

console.log('有新客户端连接啦!当前在线人数:', clients.size);

// 当收到客户端发的消息时触发message事件

ws.on('message', (message) => {

console.log('收到消息:', message.toString());

// 广播消息给所有客户端(包括发消息的人)

for (const client of clients) {

if (client.readyState === WebSocket.OPEN) { // 确保客户端连接是打开的

client.send(message.toString());

}

}

});

// 当客户端断开连接时触发close事件

ws.on('close', () => {

clients.delete(ws);

console.log('客户端断开连接,当前在线人数:', clients.size);

});

// 处理连接错误

ws.on('error', (error) => {

console.error('连接错误:', error);

});

});

console.log('Websocket服务器启动啦,监听端口3000~');

我跟你说,这里有两个关键点你得注意:

  • 客户端集合:你得把所有连接的客户端存起来,不然没法广播消息——比如用户A发“我想吃火锅”,你得把这个消息发给所有在线的用户,总不能只发给服务器自己吧?我之前写的时候,一开始没存clients,结果用户发消息只有服务器能收到,其他用户看不到,差点把室友急哭。
  • 检查连接状态:发送消息前得确认client.readyState === WebSocket.OPEN,不然要是客户端已经断开了,你还发消息,会报错。我之前没加这个判断,服务器日志里全是“无法发送消息给已关闭的连接”,后来加上就好了。
  • 第二步:写前端页面(原生JS,不用框架)

    新建个index.html文件,写前端代码。前端的逻辑很简单:建立Websocket连接,发送消息,接收消息,显示到页面上。代码给你贴出来:

    
    
    
    Websocket聊天室
    
    

    .chat-box { width: 500px; margin: 20px auto; }

    .messages { height: 300px; border: 1px solid #ddd; padding: 10px; overflow-y: auto; }

    .input-area { margin-top: 10px; display: flex; }

    .input-area input { flex: 1; padding: 5px; }

    .input-area button { padding: 5px 10px; margin-left: 10px; }

    // 建立Websocket连接(注意地址要和后端一致)

    const socket = new WebSocket('ws://localhost:3000');

    const messagesDiv = document.getElementById('messages');

    const messageInput = document.getElementById('messageInput');

    const sendBtn = document.getElementById('sendBtn');

    // 当连接成功建立时触发onopen事件

    socket.onopen = () => {

    addMessage('系统提示:连接成功,可以发消息啦!');

    };

    // 当收到服务器发的消息时触发onmessage事件

    socket.onmessage = (event) => {

    addMessage(event.data);

    };

    // 当连接断开时触发onclose事件

    socket.onclose = () => {

    addMessage('系统提示:连接断开了...');

    // 这里可以加断开重连逻辑(比如3秒后重新连接)

    setTimeout(() => {

    window.location.reload(); // 简单的重连方式,刷新页面

    }, 3000);

    };

    // 发送消息的点击事件

    sendBtn.addEventListener('click', () => {

    const message = messageInput.value.trim();

    if (message) {

    socket.send(用户:${message}); // 加个前缀区分用户

    messageInput.value = ''; // 清空输入框

    }

    });

    // 按回车键发送消息(优化体验)

    messageInput.addEventListener('keypress', (e) => {

    if (e.key === 'Enter') {

    sendBtn.click();

    }

    });

    // 把消息添加到页面上的函数

    function addMessage(text) {

    const messageP = document.createElement('p');

    messageP.textContent = text;

    messagesDiv.appendChild(messageP);

    // 自动滚动到最底部,方便看最新消息

    messagesDiv.scrollTop = messagesDiv.scrollHeight;

    }

    这里我要跟你强调几个细节:

  • 连接地址:前端的ws://localhost:3000得和后端的端口一致,不然连不上。我之前帮朋友做的时候,他后端用了3001端口,前端写成3000,结果一直提示“连接失败”,查了半小时才发现端口错了。
  • 断开重连:我在onclose事件里加了个setTimeout刷新页面,虽然简单,但能解决用户刷新页面或网络波动后的重连问题。你也可以写更优雅的重连逻辑,比如不刷新页面,重新new一个WebSocket实例,不过对新手来说,刷新页面已经够用来。
  • 自动滚动messagesDiv.scrollTop = messagesDiv.scrollHeight——这个很重要!不然消息多了,用户得手动拉滚动条才能看到最新消息,体验特别差。我之前没加这个,室友说“每次发消息都得往下拉,太麻烦了”,加了之后他才满意。
  • 第三步:跑起来试试,看看效果

    现在,你打开终端,在websocket-chat文件夹下输node server.js启动后端服务器,然后用浏览器打开index.html——你会看到“系统提示:连接成功,可以发消息啦!”。然后你再打开另一个浏览器窗口(或标签页),也打开index.html,在其中一个窗口输入“今晚吃火锅不?”,点发送,另一个窗口马上就能收到消息——是不是超神奇?

    我去年做的时候,第一次看到两个窗口实时同步消息,差点跳起来——终于搞定了!室友当时在旁边看着,说“这才像话嘛”,后来他把这个聊天室放到他的美食社群里,用户反馈“发消息比微信还快”,他还请我吃了顿火锅。

    这些踩坑点你一定要注意,不然写好的代码也会翻车

    我把去年做聊天室时踩过的坑,全给你列出来,帮你避坑:

  • 跨域问题:如果你的前端和后端不在同一个域名(比如前端是http://localhost:5500,后端是ws://localhost:3000),会出现跨域错误。解决办法是在后端设置允许跨域——比如用ws库的话,可以加headers配置:
  • javascript

    const wss = new WebSocket.Server({

    port: 3000,

    headers: {

    'Access-Control-Allow-Origin': '' // 允许所有域名跨域(开发环境用,生产环境要改具体域名)

    }

    });

  • 心跳检测:有时候网络波动会导致连接“假死”——比如用户没关页面,但连接已经断了,发消息发不出去。解决办法是加心跳检测:后端每隔30秒给客户端发个“ping”,客户端收到后回复“pong”,如果后端没收到“pong”,就断开连接重新连。我之前没加这个,用户反馈“有时候发消息没反应,得刷新页面”,加了之后再也没出现过这个问题。
  • 消息格式: 用JSON格式发消息,比如{ "username": "小明", "content": "今晚吃火锅", "time": "2024-05-20 18:00" }——这样方便处理复杂消息(比如昵称、时间、表情)。我之前用纯文本发消息,后来要加昵称的时候,得拆字符串,特别麻烦,换成JSON就简单多了。
  • 你按我上面说的步骤做,绝对能写出能用的Websocket聊天室代码。要是碰到问题,比如连接不上、消息发不出去,你可以先检查这几点:后端服务器有没有启动?端口对不对?跨域有没有处理?要是还解决不了,欢迎在评论区告诉我,我帮你看看——毕竟我踩过的坑比你吃过的米饭还多!

    对了,你要是想加更多功能,比如用户登录、表情、历史消息,也可以留言告诉我,我下次再写篇教程教你。现在赶紧去试代码吧,等你成功的好消息!


    Websocket和HTTP有什么不一样?为什么聊天室要用Websocket?

    Websocket和HTTP的区别其实像“打电话”和“发消息”——HTTP是客户端主动问、服务器答完就挂,单向通信,延迟高还费资源;Websocket是建立长连接,客户端和服务器都能主动发消息,双向通信,延迟低又省资源。

    聊天室需要实时同步消息,比如你发“吃火锅不”,得让所有人立刻收到,用HTTP的话得每隔1秒问服务器有没有新消息,不仅延迟高,服务器还得处理一堆重复请求,而Websocket刚好解决这个问题,所以聊天室肯定选Websocket啊。

    用Node.js搭Websocket后端必须用ws库吗?有没有其他选择?

    不是必须,但ws库是Node.js生态里最常用的Websocket库,Node.js官方文档都推荐用它,安装简单、API也直观,新手入门特别合适。

    当然也有其他选择,比如socket.io,它封装了更多功能(比如自动重连、房间管理),但对刚学Websocket的人来说,先把ws库吃透,再学其他库会更轻松。

    前端写Websocket聊天室必须用框架吗?原生JS能不能搞定?

    完全不用!文中的前端代码就是用原生JS写的,没有用React、Vue这些框架,步骤也很简单——建立连接、监听消息、发送消息,几个函数就搞定了。

    原生JS写Websocket的好处是不用学框架语法,直接跟浏览器的Websocket API打交道,更能理解底层逻辑,新手跟着文中的代码一步步来,肯定能写出能跑的前端页面。

    Websocket聊天室启动后,两个窗口发消息不同步是怎么回事?

    首先检查后端有没有“存储客户端集合”的逻辑——比如文中用const clients = new Set()存所有连接的客户端,要是没这一步,服务器收到消息后没法广播给所有客户端,自然不同步。

    再看看广播消息的代码有没有写对,比如有没有循环clients集合,有没有判断client.readyState === WebSocket.OPEN,要是没判断连接状态,断开的客户端会收不到消息,也会导致不同步。

    Websocket聊天室遇到跨域错误怎么办?

    跨域一般是因为前端和后端的域名或端口不一样,比如前端用localhost:5500,后端用localhost:3000,浏览器就会拦下来。

    解决办法是在后端加跨域配置——比如用ws库的话,创建服务器时加headers配置,把Access-Control-Allow-Origin设为(开发环境用,生产环境要改具体域名),这样浏览器就不会拦截请求了。