Websoket——聊天室

本文介绍了WebSocket协议,它是一种在浏览器和服务器间实现全双工通信的协议,通过HTTP建立连接后切换到WebSocket。WebSocket连接过程包括升级HTTP请求,服务器返回101状态码确认。接着,通过一个聊天室案例展示了WebSocket和Socket.IO的使用,包括项目初始化、设置静态资源、监听连接和消息传递。Socket.IO提供了服务端和客户端库,简化了实时通信的实现。通过示例代码,演示了如何创建WebSocket服务器,监听连接和消息事件。最后,提到了Socket.IO的自动提供客户端和加载到浏览器的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. WebSocket 协议介绍

WebSocket 协议实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。它与HTTP一样通过已建立的TCP连接来传输数据,但是它和HTTP最大不同是:

  1. WebSocket是一种双向通信协议。在建立连接后,WebSocket服务器端和客户端都能主动向对方发送或接收数据,就像Socket一样;
  2. WebSocket需要像TCP一样,先建立连接,连接成功后才能相互通信。

2. WebSocket 协议的建立过程

接下来我们来了解一下 WebSocket 协议的建立过程:

WebSocket 连接必须由浏览器发起,请求协议是一个标准的HTTP请求(也就是说,WebSocket的建立是依赖HTTP的)。请求报文格式如下:
在这里插入图片描述

该请求和普通的HTTP请求有几点不同:

其中 HTTP 头部字段 Upgrade: websocketConnection: Upgrade很重要,告诉服务器通信协议将发生改变,转为 WebSocket 协议。
Sec-WebSocket-Key是用于标识这个连接,并非用于加密数据;
Sec-WebSocket-Version指定了WebSocket的协议版本。
支持 WebSocket 的服务器端在确认以上请求后,应返回状态码为101 Switching Protocols的响应:

该响应代码 101 表示本次连接的HTTP协议即将被更改,更改后的协议就是 Upgrade: websocket 指定的WebSocket协议。

版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用 WebSocket 的 API ,就不需要关心这些。

现在,一个 WebSocket 连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。

为什么 WebSocket 连接可以实现全双工通信而 HTTP 连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP 协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,接下来的通信就不使用 HTTP 协议了,直接互相发数据。

安全的 WebSocket 连接机制和 HTTPS 类似。
首先,浏览器用 wss://xxx 创建 WebSocket 连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS 连接升级为 WebSocket 连接,底层通信走的仍然是安全的 SSL/TLS 协议。

3. 聊天室案例效果

在这里插入图片描述

案例初始化
  1. 建立项目所需文件夹

    · public 静态资源
    · model 数据库操作
    · route 路由
    · view 模板

  2. 初始化项目描述文件
    · npm init -y

    (我的是在powershell里头写命令的,没有询问作者姓名什么的。vs里头可以👇)
    在这里插入图片描述

  3. 下载项目所需第三方模块
    · npm install express
    · npm install --save socket.io

都是在最外面的项目文件夹中下载(blog),初始化也是

要保存 dependencies 信息, 可以用 npm install --save

  1. 创建网站服务器

app.js 项目的入口文件也是主文件

var express = require('express');

// App的设置
var app = express(),
 	server = app.listen(7000,function(){
 		console.log("正在监听7000端口的请求");

 	})
		
  1. 展示静态页面(构建模块化路由)

页面的样式就跳过了,有时间可以写个自己喜欢的呢。

为了在页面中展示相对应的内容,此处用到了中间件

// 頭部添加以下這個
var  path = require('path');

//开放静态资源文件
app.use(express.static(path.join(__dirname,"public")));//如何访问?按路径输入该文件下的网页就可。
//(http://localhost/home/default.html)不需要再包含public,而是在public下直接进入

两种访问都可以
在这里插入图片描述
在这里插入图片描述

  1. 服务端 引入socket.IO并设置

  2. 监听客户端是否与服务器建立连接

  • socket.id 每个客户端进来都有个id的
    在这里插入图片描述
  1. 连接完成,开始处理逻辑内容
    聊天室功能:
    • 广播信息, 只要进到了聊天室就可以收到别人发送的消息
    1. 可以看到别人正在输入中… 但是自己输入的时候看不到自己在输入
      需要监听message输入的事件,

在这里插入图片描述

在这里插入图片描述


4. 关于 Socket.IO

Socket.IO 由两部分组成:

  • 一个服务端用于集成 (或挂载) 到 Node.JS HTTP 服务器: socket.io
  • 一个加载到浏览器中的客户端: socket.io-client

开发环境下, socket.io 会自动提供客户端。正如我们所见,到目前为止,我们只需要安装一个模块:

npm install --save socket.io

这会安装模块并添加依赖到 package.json。在 index.js 文件中添加该模块:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
    

我们通过传入 http (HTTP 服务器) 对象初始化了 socket.io 的一个实例。 然后监听 connection 事件来接收 sockets, 并将连接信息打印到控制台。

在 index.html 的</body>标签中添加如下内容:
(也可以引入cdn)

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。

请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。

重新加载服务器和网站,你将看到控制台打印出 “a user connected”。
尝试打开多个标签页,可以看到多条信息:

每个 socket 还会触发一个特殊的 disconnect 事件:

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

你可以多次刷新标签页来查看效果:


参考文章:

  1. WebSocket 协议介绍及 WebSocket API 应用
  2. w3c里的socket.io官方文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值