如何实现类似QQ消息的会话功能?🤔

前言

在面试考题中,如果面试官问关于http协议相关的知识或者直接让你实现一个类似QQ消息的发送,这时候就可以讲到websocket相关的知识了。

那就让我们先来了解一下基础协议相关的技术,再实现会话功能。

1.基础协议与技术

1.1 TCP/IP 协议

TCP/IP 是互联网的基础协议,负责数据的传输。它通过三次握手建立连接,并通过四次挥手断开连接。这种机制确保了数据传输的可靠性。

1.2 HTTP 协议与 Socket

HTTP 协议是应用层协议,通常用于浏览器与服务器之间的通信。它是无状态的,即每次请求都是独立的,服务器不会记住之前的请求。而 Socket 是一种更底层的通信机制,可以实现长连接、消息推送和广播等功能。

1.3 B/S 架构

B/S(Browser/Server)架构是常见的Web应用架构,用户通过浏览器与服务器进行交互。在这种架构下,即时通讯功能通常需要借助 WebSocket 协议来实现。

2. HTTP 与 WebSocket 的区别

先上图表:

2.1 状态性

  • HTTP 是无状态的,每次请求都是独立的,服务器不会记住客户端的状态。
  • WebSocket 是有状态的:服务器会为每个连接保持一个持久的双向通信通道。开发者可以自定义唯一的标识符(如 Socket ID)来管理和区分不同的客户端连接.

2.2 通信方式

  • HTTP 是单向的,客户端发起请求,服务器返回响应,服务器不能主动向客户端发送消息。
  • WebSocket 是双向的,客户端和服务器可以随时向对方发送消息。

2.3 通信模式

  • HTTP 是基于请求-响应的,客户端发起请求后,服务器返回响应,通信结束。
  • WebSocket 是基于事件的,客户端和服务器可以通过事件(如 onmessage)来实时接收消息。

3. WebSocket 服务搭建流程

3.1 基于 HTTP 服务访问聊天页面

首先,我们需要基于 HTTP 服务访问聊天页面。用户通过浏览器访问 http://localhost:3001/,服务器返回一个包含 WebSocket 连接的 HTML 页面。(在这里使用了koa框架和koa-websocket来实现)

js 复制代码
const Koa = require('koa');
const websocket = require('koa-websocket');
const app = websocket(new Koa()); // 开启一个应用实例
const clients = new Set();

app.use(async (ctx, next) => {
    ctx.body = `
    <html>
      <body>
        <div id="messages" style="height: 300px; overflow-y: scroll;"></div>
        <input type="text" id="messageInput" />
        <button onclick="sendMessage()">发送</button>
        <script>
          const ws = new WebSocket('ws://localhost:3001');
          ws.onmessage = function(event) {
            const messages = document.getElementById('messages');
            messages.innerHTML += "<div>" + event.data + '<br/>';
          }
          function sendMessage() {
            const msg = document.getElementById('messageInput').value.trim();
            ws.send(msg);
          }
        </script>
      </body>
    </html>
    `;
});

3.2 WebSocket 连接建立

当用户访问页面后,浏览器会通过 WebSocket 协议向服务器发起连接请求。服务器返回状态码 101 Switching Protocols,表示协议切换成功,后续通信将使用 WebSocket 协议。

js 复制代码
app.ws.use(async (ctx, next) => {
    clients.add(ctx.websocket);
    ctx.websocket.on('message', (message) => {
        for (const client of clients) {
            client.send(message.toString()); // 服务器广播给所有的用户
        }
    });
    ctx.websocket.on('close', () => {
        clients.delete(ctx.websocket);
    });
});

// http 伺服
app.listen(3001,()=>{
    console.log('server is running at port 3001')
})

3.3 消息的发送与接收

在 WebSocket 连接建立后,客户端和服务器可以通过 send 方法发送消息,并通过 onmessage 事件接收消息。服务器可以将接收到的消息广播给所有连接的客户端,实现群聊功能。

3.4 实现效果:

打开两个伺服端口,模拟两个用户之间进行对话,在第一个用户中发送消息,第二个接收,第二个用户发送消息,第一个用户也成功接收

4.执行流程:

当你打开页面并发送一个消息时:

  1. 加载页面

    • 用户访问ws://localhost:3001(或通过其他方式触发Koa应用),Koa应用返回一段HTML代码作为响应。
    • 浏览器解析这段HTML代码,并渲染出一个包含输入框和按钮的简单界面。
  2. 建立WebSocket连接

    • 页面加载完成后,JavaScript代码立即创建一个新的WebSocket实例ws = new WebSocket('ws://localhost:3001'),尝试与服务器建立WebSocket连接。
    • 服务器端通过app.ws.use()注册的中间件监听到新的WebSocket连接请求,并将该连接添加到clients集合中,这标志着WebSocket连接成功建立。
  3. 用户输入消息并点击发送按钮

    • 当用户在输入框内输入文本并点击"发送"按钮后,sendMessage()函数被调用。
    • 函数获取输入框内的值,通过WebSocket对象的send()方法将消息发送至服务器。
  4. 服务器接收并广播消息

    • 服务器端通过监听WebSocket连接的message事件来接收客户端发来的消息。
    • 收到消息后,服务器遍历所有已连接的客户端(存储于clients集合中),并通过每个客户端的send()方法将消息转发给它们,实现消息的广播。
  5. 客户端显示接收到的消息

    • 客户端通过监听WebSocket对象的onmessage事件来处理从服务器接收到的消息。
    • 每当收到新消息时,更新页面上的<div id="messages">元素内容,将新消息追加到已有消息列表的末尾,从而实现实时显示消息的功能。

END

如果觉得哥们的文章对你有帮助,也请给我点个赞吧!

相关推荐
G等你下课几秒前
React 事件机制原理
前端·react.js
Pedantic6 分钟前
为什么 Swift 字符串不能用 `myString[3]` 随便取字符?
前端·后端
RichardLai888 分钟前
Kotlin Flow:构建响应式流的现代 Kotlin 之道
android·前端·kotlin
Apifox9 分钟前
提交代码后如何自动触发 Apifox 的自动化测试?
前端·后端·测试
qiyue7711 分钟前
AI编程专栏(四) - 提示词技术,如何写编程提示词
前端·ai编程
DoraBigHead14 分钟前
【JS三兄弟谁是谁】搞懂 splice、slice、split,只需一杯奶茶的时间!
前端·javascript·面试
国家不保护废物15 分钟前
前端存储与后端服务的奇妙冒险:一个Node.js服务器的诞生记(cookie实现用户登入)
前端·javascript·后端
前端付豪16 分钟前
2、前端架构三要素:模块化、工程化、平台化
前端·javascript·架构
遂心_16 分钟前
深入剖析React待办事项应用:Hooks、组件化与性能优化实战
前端·react.js·前端框架
bo5210017 分钟前
浏览器事件机制详解以及发展史
前端·面试·浏览器