WebSocket 入门:简易聊天室

大家好,我是前端西瓜哥,今天我们用 WebSocket 来实现一个简单的聊天室。

WebSocket 是一个应用层协议,有点类似 HTTP。但和 HTTP 不一样的是,它支持真正的全双工,即不仅客户端可以主动发消息给服务端,服务端也可以主动发消息给客户端。

尤其是后者,让我们不用再基于 HTTP 长轮询或短轮询的低效方式来实现服务端通知。相比 HTTP,WebSocket 的服务端推送更轻量,并能减少服务端的压力。

服务端

nodejs 并没有提供原生的 websocket 模块。如果要实现,需要基于 net 模块,根据 websocket 标准去做实现。

因为实现很复杂,所以西瓜哥我选择直接用第三库 ws。

yarn add ws

类似 nodejs 原生的 http 等模块,ws 库支持 WebSocket 的服务端或客户端, 提供偏底层的 API。

我们显示服务端代码:

import { WebSocketServer } from "ws";

// 创建一个 ws 服务
const wsSever = new WebSocketServer({
  port: 6060,
});

// 每当一个客户端进行了 ws 连接,就会创建一个 ws 对象
wsSever.on("connection", (ws) => {
  // 新客户端连接时,广播
  wsSever.clients.forEach((client) => {
    client.send(`有人进入聊天室,当前聊天室人数:${wsSever.clients.size}`);
  });

  // 广播任何客户端发送的消息
  ws.on("message", (data) => {
    const msg = data.toString();
    wsSever.clients.forEach((client) => {
      client.send(msg);
    });
  });

  // 当有客户端退出时,广播
  ws.on("close", () => {
    wsSever.clients.forEach((client) => {
      client.send(`有人退出了聊天室,当前聊天室人数:${wsSever.clients.size}`);
    });
  });
});

每当一个客户端进行了 websocket 连接,都会触发 wsServer 的 connection 事件,然后拿到一个 ws 对象。

这个 ws 对象代表了某个客户端和服务端的连接,我们可以通过它来接收对应客户端的消息,和服务端对指定客户端进行主动消息推送。

新创建的 ws 对象会在建立连接时保存到 wsServer.clients 集合下,并在关闭连接后移除。所以我们可以利用这个 wsServer.clients 来进行广播,实现聊天室功能。

客户端

客户端使用原生的 WebSocket 对象,来和服务端进行 websocket 连接。

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

ws.addEventListener('message', (event) => {
  const div = document.createElement('div');
  div.innerText = event.data;
  document.body.append(div);
})

// 点击发送按钮,将输入框中的内容发送给服务器
const input = document.querySelector('input');
const btn = document.querySelector('button');
btn.onclick = () => {
  ws.send(input.value);
  input.value = '';
}

效果

在这里插入图片描述

改为使用 Socket.IO

ws 库是偏底层的实现,比较简单。

另一个库 Socket.IO 的底层使用了 ws,并做功能上的增强,提供更多的能力。

相比 ws,Socket.IO 能够做到:

  1. 如果浏览器不支持 WebSocket,回退为 HTTP 长轮询方案来模拟 WebSocket( WebSocket 于 2011 年完成 RFC,已经很久了,目前来说主流浏览器都已经支持 WebSocket 了,还不支持 WebSocket 的浏览器是屑);
  2. 使用心跳包机制实现了自动重连。
  3. 包缓存。断连时发送数据,会将数据保存下来,等重新连接后再发送;
  4. 自定义事件支持;
  5. 广播;

相比自己去一个个实现,使用流行的轮子可能是更好的选择。

我们将前面的功能用 Socket.IO 实现一下。

服务端:

import { Server } from "socket.io";

// socket.io v3.x 开始默认不允许跨域,需要在配置显式设置为允许跨域
const io = new Server(6060, { cors: { origin: "*" } });

io.on("connection", (socket) => {
  // 新客户端连接时,广播
  io.emit("chat", `有人进入聊天室,当前聊天室人数:${io.engine.clientsCount}`);

  // 广播任何客户端发送的消息
  socket.on("chat", (data) => {
    io.emit("chat", data);
  });

  // 当有客户端退出时,广播
  socket.on("disconnect", () => {
    io.emit("chat", `有人退出了聊天室,当前聊天室人数:${io.engine.clientsCount}`);
  });
});

需要特别注意的是,Socket.IO 的 v3.x 版本开始,默认不允许跨域,需要在配置显式设置为允许跨域。

客户端:

const socket = io('ws://localhost:6060');

socket.on('chat', (data) => {
  const div = document.createElement('div');
  div.innerText = data;
  document.body.append(div);
})

// 点击发送按钮,将输入框中的内容发送给服务器
const input = document.querySelector('input');
const btn = document.querySelector('button');
btn.onclick = () => {
  console.log('发送');
  socket.emit('chat', input.value);
  input.value = '';
}

Socket.IO 优点是实现了生产环境需要的底层非业务能力,让我们能更心无旁骛地去编写业务代码。

缺点是丢失了灵活性。因为做了定制化,所以需要配套使用 Socket.IO 的客户端和服务端库的包,某种意义脱离了网络协议标准。在出现跨语言(比如前端是 JS,后端是 Java)的场景时,需要提供对应的语言的 Socket.IO 实现。

demo

demo 已经放到 github 上了,使用方法在 README.md 中有说明。

https://github.com/F-star/websocket-chat-demo

结尾

本文演示了 WebSocket 简易的聊天室功能是如何实现的,希望对你有所帮助。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
简易聊天本次实验的目的是通过以下题目掌握JSP内置对象,包括:request,response,session,application等。 (1)制作简易聊天,能够实现简单的页面聊天功能。 (2)制作网页计数器,要求相同的窗口内刷新页面访问次数并不增加,并且用图片来显数字。1、 熟悉request、response、session、application、out等内置对象; 2、 选择制作网页计数器程序需准备数字图片;1、进入jsp子目录,编写简易聊天的JSP程序,聊天的需要实现的基本功能:输入昵称、聊天。 2.根据功能编写页面代码。二、网页计算器 利用内置对象application <html> <head> <base href="<%=basePath%>"> <title>My JSP 'Counter.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 您是第位访问者! </body> </html> 简易聊天本次实验的目的是通过以下题目掌握JSP内置对象,包括:request,response,session,application等。 (1)制作简易聊天,能够实现简单的页面聊天功能。 (2)制作网页计数器,要求相同的窗口内刷新页面访问次数并不增加,并且用图片来显数字。1、 熟悉request、response、session、application、out等内置对象; 2、 选择制作网页计数器程序需准备数字图片;1、进入jsp子目录,编写简易聊天的JSP程序,聊
### 回答1: Websocket聊天是一种基于Websocket技术的实时通讯应用,可以实现多人在线聊天、发送图片、文件等功能。它是一种全双工通信协议,通过建立客户端和服务器之间的长连接,实现双向通信。相比于传统的HTTP协议,Websocket协议具有更低的延迟、更高的效率、更少的网络负荷等优点,因此被广泛应用于实时通讯领域。 Websocket聊天的实现可以分为客户端和服务器两个部分。客户端一般是通过浏览器提供的Websocket API来实现,而服务端则需要使用专门的Websocket服务器,例如Node.js的Socket.IO、Java的Tomcat等。客户端和服务器之间通过Websocket协议进行通信,客户端可以发送消息、文件等数据,服务器则接收消息并进行处理,然后将消息转发给其他客户端。 Websocket聊天的实现过程中需要考虑多个方面,例如安全性、可扩展性、性能等问题。例如,需要对用户身份进行认证、对数据进行加密传输、对消息进行过滤和校验等。同时,需要考虑如何处理大量的并发连接,如何保证消息的可靠性、顺序性等问题。 总之,Websocket聊天是一种非常实用的实时通讯应用,可以为用户提供高效、便捷、可靠的聊天体验。 ### 回答2: WebSocket是一种用于在浏览器和服务器之间进行实时双向通信的通信协议。WebSocket聊天是一个基于WebSocket技术的实时聊天应用。 WebSocket聊天通过WebSocket协议建立了一个双向通信通道,在浏览器和服务器之间实现实时的消息传递。用户可以在浏览器中发送消息,服务器会将消息实时地推送给其他在线用户,其他用户也可以实时地向服务器发送消息,服务器会将这些消息分发给其他在线用户。 WebSocket聊天具有以下特点: 1. 实时性:WebSocket聊天实现了服务器和浏览器之间的实时双向通信,用户可以实时地发送和接收消息。 2. 高效性:与传统的轮询方式相比,WebSocket采用了事件驱动的方式,减少了不必要的数据传输,提高了通信效率。 3. 可扩展性:WebSocket聊天可以添加更多功能,如发送图片、语音等,增加用户体验。 4. 安全性:WebSocket聊天可以通过使用SSL/TLS协议进行加密,确保通信过程的安全性和用户信息的保密性。 5. 跨平台:WebSocket聊天支持多种浏览器和操作系统,用户可以在不同的设备上使用。 总之,WebSocket聊天是一种基于WebSocket协议的实时聊天应用,通过实现浏览器和服务器之间的双向通信,实现用户之间的实时消息传递。它具有实时性、高效性、可扩展性、安全性和跨平台等特点,是一种很好的实时通信解决方案。 ### 回答3: WebSocket聊天是一种基于WebSocket协议实现的实时通信的应用程序。与传统的HTTP请求-响应模式不同,WebSocket提供了一个持久的双向通信通道,允许服务器主动向客户端推送数据。 在WebSocket聊天中,用户可以通过浏览器或类似应用程序连接到服务器,建立起WebSocket连接。一旦连接建立成功,用户可以与其他连接到同一服务器的人实时交流,发送和接收消息。 聊天通常包括以下功能: 1. 用户认证:用户可以通过提供用户名和密码等凭证进行认证,确保只有授权用户才能进入聊天。 2. 房间管理:聊天可以分为多个房间,用户可以选择进入感兴趣的房间。聊天管理员可以创建、编辑和删除房间。 3. 消息发送:用户可以通过输入框输入消息并发送给聊天中的其他人。发送的消息可以是文本、图片、文件等。 4. 消息接收:当有新消息时,聊天会将该消息实时推送给所有连接到聊天的用户,用户可以看到其他人发送的消息。 5. 在线用户列表:聊天可以显示当前在线的用户列表,包括用户名、头像等信息。用户可以通过点击在线用户的头像或用户名与之私聊。 6. 表情和文件上传:聊天可以支持发送表情和文件。用户可以选择从本地上传文件并发送给聊天中的其他人。 WebSocket聊天可以用于各种场景,如在线客服、团队协作、社交网络等。它提供了实时通信的能力,可以有效地促进人与人之间的交流和沟通。同时,它也需要服务器端提供相应的支持和处理逻辑,保证聊天的稳定运行和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值