前言

本文只介绍实现的核心代码,目的是记录和分享知识。若感兴趣可以往下看,在文章最后贴上了仓库地址。前端使用 Vite + Vue3;后端使用 Knex + Express。

Room 的概念

私密 Room

在开始做私聊功能之前,要掌握 Socket.io 的 Room 概念,当一个客户端连接到服务器时就会产生一个唯一的标识符,作为客户端的 ID。socket.id就可以拿到标识符:

server.on("connection", (socket: any) => {
console.log(socket.id);
});

一个socket.id就是一个私密的 Room,客户端 A 拿到客户端 B 的私密 Room,就可以通过socket.to(room).emit('echo private', "Hello")向客户端 B 发送私密信息。

公共 Room

任意一个字符都可以作为公共 Room,区别于私密 Room。客户端通过socket.join(room)加入公共 Room,服务器就可以使用server.to(room).emit('public')发送群聊消息的事件,而客户端只需要监听这个事件就可以拿到群聊消息。下图是公共 Room 的结构图:

在本篇博文中,这一小节只是介绍 Socket.io 中私密 Room 和公共 Room 的区别。

开始

没有 Socket.io 基础的同学请看入门 Socket.io

服务器

下面是服务器转交私密消息的实现步骤和代码:

  1. 服务器监听连接事件,当客户端 A 连接之后,服务器就监听客户端 A 的私密信息事件。
  2. 当客户端 A 发送私密信息事件之后,服务器就把私密信息转发给客户端 B。
server.on("connection", (socket: any) => {
socket.on("emit-private", (e: any) => {
socket.to(e.socket_id).emit("echo-private", e);
});
});

客户端

客户端的实现步骤稍微复杂一些,客户端发送的私密消息需要封装到类,通过 emit 发送给服务器,再由服务器去转交消息给目标客户端。

(1)封装消息类:

export class Message {
public username: string;
public text: string;
public avatar: string;
public popColor: string;
public type?: string;
public socket_id?: string; constructor(username: string, text: string, avatar: string, popColor: string, type?: string, socketId?: string) {
this.username = username;
this.text = text;
this.avatar = avatar;
this.popColor = popColor;
this.type = type;
this.socket_id = socketId;
}
}

接收私密消息一方需要知道消息的用户名、消息文本、头像、Socket ID(私密 Room 标识符),其他的字段忽略不看。

(2)发送私密消息

下面是聊天室的 setup(组合式)代码,忽略了大量细节,只保留了核心代码:

  1. 导入 socket-client 模块,连接服务器。
  2. 客户端中输入好消息之后,点击按钮触发事件,客户端发送emit-private给服务器。
  3. 客户端监听服务器转交的私密消息。
import { onMounted, ref } from "vue";
import { io } from "socket.io-client";
import { Message } from "../typescript/standard"; const socket = io("http://localhost:3000");
const methods = {}; onMounted(() => {
socket.on("echo-private", (e) => {
console.log(e);
}); methods.onSendText = (text: string) => {
let message = new Message(username, text, avatar, popColor, "others", socket_id);
socket.emit("emit-private", message);
};
});

演示

目前有三个客户端已经连接到服务器,下图是每一个客户端的私密 Room 标识符,它是唯一的,且由服务器分配的:

下图是两个客户端进行私聊,另一个客户端不能接收消息的演示截图:

左边是客户端 A,右上是客户端 B,右下是客户端 C。客户端 A 给客户端 B 互相发送私密消息,客户端 C 不能接收。

最后

想要查看完整的实现步骤,如果喜欢的话,请给我的仓库点一个 Star 吧,再给博文也点个赞!!!

  1. 前端项目:chatroom
  2. 后端项目:chatroom-serve

目前还在继续实现中...

Socket.io + Knex 实现私聊聊天室的更多相关文章

  1. 利用socket.io+nodejs打造简单聊天室

    代码地址如下:http://www.demodashi.com/demo/11579.html 界面展示: 首先展示demo的结果界面,只是简单消息的发送和接收,包括发送文字和发送图片. ws说明: ...

  2. html5的新通讯技术socket.io,实现一个聊天室

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 基于Node.js+socket.IO创建的Web聊天室

    这段时间进了一个新的项目组,项目是用Appcan来做一个跨平台的移动运维系统,其中前台和后台之间本来是打算用WebSocket来实现的,但写好了示例后发现android不支持WebSocket,大为受 ...

  4. vue + socket.io实现一个简易聊天室

    vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那 ...

  5. 基于react+react-router+redux+socket.io+koa开发一个聊天室

    最近练手开发了一个项目,是一个聊天室应用.项目虽不大,但是使用到了react, react-router, redux, socket.io,后端开发使用了koa,算是一个比较综合性的案例,很多概念和 ...

  6. 利用socket.io实现多人聊天室(基于Nodejs)

    socket.io简单介绍 在Html5中存在着这种一个新特性.引入了websocket,关于websocket的内部实现原理能够看这篇文章.这篇文章讲述了websocket无到有,依据协议,分析数据 ...

  7. Vue3 + Socket.io + Knex + TypeScript 实现可以私聊的聊天室

    前言 下文只在介绍实现的核心代码,没有涉及到具体的实现细节,如果感兴趣可以往下看,在文章最后贴上了仓库地址.项目采用前后端模式,前端使用 Vite + Vue3 + TS:后端使用 Knex + Ex ...

  8. 以C#编写的Socket服务器的Android手机聊天室Demo

    内容摘要 1.程序架构 2.通信协议 3.服务器源代码 4.客户端源代码 5.运行效果 一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.WCF这些具有双向通信的协议或 ...

  9. 高级IO复用应用:聊天室程序

    简单的聊天室程序:客户端从标准输入输入数据后发送给服务端,服务端将用户发送来的数据转发给其它用户.这里采用IO复用poll技术.客户端采用了splice零拷贝.服务端采用了空间换时间(分配超大的用户数 ...

  10. netty-socket.io点对点通讯和聊天室通讯

    netty-socketio是基于netty的socket.io服务实现,可以无缝对接前端使用的socketio-client.js. 相对于javaee的原生websocket支持(@serverE ...

随机推荐

  1. 【中间件】Docker

    一.Docker (一)基础概念 1.概念 是linux容器的一种封装,它是最流行的Linux容器解决方案,由go语言开发 提供简单易用的容器使用接口,方便创建.使用和销毁 2.应用场景 自动打包.持 ...

  2. 干电池升压3.3V芯片

    PW5100适用于一节干电池升压到3.3V,两节干电池升压3.3V的升压电路,PW5100干电池升压IC. 干电池1.5V和两节干电池3V升压到3.3V的测试数据 两节干电池输出500MA测试: PW ...

  3. 简单的Dos命令学习

    Dos命令学习 打开CMD的方式 从菜单栏打开,windows系统里 win+R 输入cmd 在任意文件夹下,按住shift+右键,点击打开PowerShell 在资源管理器的地址栏前面加上cmd+空 ...

  4. Docker的作用

    绝大部分应用,开发者都可以通过docker build创建镜像,通过docker push上传镜像,用户通过docker pull下载镜像,用docker run运行应用. 用户不需要再去关心如何搭建 ...

  5. linux-微服务-jar包部署指令

    1 orderservice docker build -t orderservice . docker run -d -p 8084:8084 --name orderservice orderse ...

  6. Django 之swagger中尝试调试post请求时返回 "detail": "JSON parse error - Expecting value: line 1 column 1 (char)

    swagger已配置OK,但发送POST请求时一直显示数据格式错误,怪异.... 经过各种查找资料,才发现setting.py文件中缺少配置 配置完成后重启服务,再次尝试发送POST请求,不会再报格式 ...

  7. [IOI2016] shortcut

    有显然的 \(O(n^3)\) 做法,可以获得 \(38pts\).(退火在洛谷上能跑 \(75pts\)) 答案具有单调性,考虑二分一个 \(M\) 并判断.列出 \(i\) 到 \(j\) 的距离 ...

  8. mac下 idea 注释快捷键冲突

    你好,我是悦创. 博客首发:https://bornforthis.cn/posts/28.html 打开偏好设置,将冲突的快捷键关掉,就可以解决 idea 使用注释快捷键,会打开 help 页面的问 ...

  9. python进阶之路16 模块入门

    索引取值与迭代取值的差异 l1 = [11,22,33,44,55] 1.索引取值 可以任意位置任意次数取值 不支持无序类型的数据取值 2.迭代取值 只能从前往后依次取值无法后退 支持所有类型的数据取 ...

  10. P3845 [TJOI2007]球赛

    简要题意 \(T\) 组数据,每一组数据给出 \(n\) 个数对 \((a,b)\).你需要将其分为几组,使得组单调不降.求最小组数. 思路 模拟赛考的题. 先来介绍 Dilworth 定理: 对于任 ...