前言

下文只在介绍实现的核心代码,没有涉及到具体的实现细节,如果感兴趣可以往下看,在文章最后贴上了仓库地址。项目采用前后端模式,前端使用 Vite + Vue3 + TS;后端使用 Knex + Express + TS。目前项目还没有完全实现,文章的目的是记录阶段性“胜利”和分享知识。

关于搭建 TS 项目请看搭建 Webpack + TypeScript + Babel 的项目或者JavaScript迁移

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。下文只介绍实现私聊功能的基本步骤,不展示细节,比如 UI 的设计。

服务器

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

  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"); 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 不能接收。

最后

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

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

目前还在继续实现中,目的是做一个可以发送图片和表情的,私聊、群聊功能的聊天室。

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

  1. socket.io+angular.js+express.js做个聊天应用(三)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/www19940501a/article/details/27590611 接着前面博客文章socke ...

  2. 第二个 SignalR,可以私聊的聊天室

    一.简介 上一次,我们写了个简单的聊天室,接下来,我们来整一个可以私聊的聊天室. SignalR 官方 API 文档 需求简单分析: 1.私聊功能,那么要记录用户名或用户ID,用于发送消息. 2.怎么 ...

  3. 【socket.io研究】3.手机网页间聊天核心问题

    前面我们已经说了服务器相关的一些内容,且又根据官网给出的一个例子写了一个可以聊天的小程序,但是这还远远不够呀,这只能算是应用前的准备工作.接下来,一起来考虑完善一个小的聊天程序吧. 首先,修改服务器的 ...

  4. socket.io+angular.js+express.js做个聊天应用(四)

    接着上一篇 使用angularjs构建聊天室的client <!doctype html> <html ng-app="justChatting"> < ...

  5. socket.io+angular.js+express.js做个聊天应用(二)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/www19940501a/article/details/27585321 接着上一篇 我用的开发工具 ...

  6. socket.io+angular.js+express.js做个聊天应用(一)

    node,express开发环境等安装如果已经搞好了. justhacker@justhacker-ThinkPad-Edge-E440:~/projects/nodejs$ express -e c ...

  7. Socket入门笔记 用TcpClient实现一个简易聊天室

    效果 实现思路 使用TcpListener建一个服务器,接收所有客户端发送的消息,然后由服务器再发送到其他客户端 客户端使用TcpClient,发消息给服务器,接收服务器的消息,不和其他客户端直接交互 ...

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

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

  9. 使用socket.io打造公共聊天室

    最近的计算机网络课上老师开始讲socket,tcp相关的知识,当时脑袋里就蹦出一个想法,那就是打造一个聊天室.实现方式也挺多的,常见的可以用C++或者Java进行socket编程来构建这么一个聊天室. ...

随机推荐

  1. 基于PYQT5的截图翻译工具

    基于PYQT5的截图翻译工具 功能介绍 翻译功能 截图功能(快捷键 + 截图存储到剪切板中) 文字识别OCR(基于百度API的文字识别) UI 界面 截图 截图可以使用第三方截图 或 使用PyQt5截 ...

  2. 管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程

    前言 在平常的后端项目开发中,状态机模式的使用其实没有大家想象中那么常见,笔者之前由于不在电商领域工作,很少在业务代码中用状态机来管理各种状态,一般都是手动get/set状态值.去年笔者进入了电商领域 ...

  3. 论文解读(ARVGA)《Learning Graph Embedding with Adversarial Training Methods》

    论文信息 论文标题:Learning Graph Embedding with Adversarial Training Methods论文作者:Shirui Pan, Ruiqi Hu, Sai-f ...

  4. Python中plt.plot()、plt.scatter()和plt.legend函数的用法示例

    参考:http://www.cppcns.com/jiaoben/python/471948.html https://blog.csdn.net/weixin_44825185/article/de ...

  5. ubuntu使用postfix和AWS-SES发送邮件

    在日常开发中,邮件发送是个比较常见的场景.因此出现了很多相关的软件和服务,各大云厂商也推出自己的邮件服务.今天笔者就像大家介绍一种常见的组合,AWS的邮件服务 SES 与邮件服务器 postfix 的 ...

  6. Spire.Office激活

    更新记录: 2022年5月28日 初始代码便于复用 注意:最多支持到:E-ICEBLUE Spire.Office Platinum v6.10.3 引入命名空间: using Spire.Licen ...

  7. 第六章、PXE高效网络装机、Kickstart无人值守安装

    目录 一.部署PXE远程安装服务 1PXE定义 2PXE服务优点 3搭建网络体系前提条件 4PXE实现过程讲解 二.搭建PXE远程安装服务器 三.Kickstart无人值守安装 一.部署PXE远程安装 ...

  8. JavaScript 防盗链的原理以及破解方法

    先说说防盗链的原理,http 协议中,如果从一个网页跳到另一个网页,http 头字段里面会带个 Referer.这里的Referer是由于历史原因导致了拼写错误 后来也就一直沿用.图片服务器通过检测 ...

  9. ABAP CDS - DEFINE VIEW, view_annot

    Syntax ... @annotation ... Effect Specifies Annotation annotation in the definition of a CDS view of ...

  10. 拒绝蛮力,高效查看Linux日志文件!

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 日常分析问题时,会频繁地查看分析日志,但如果蛮力去查看日志,耗时费力还不一定有效果,因此我总结了在Linux常用的 ...