前言

下文只在介绍实现的核心代码,没有涉及到具体的实现细节,如果感兴趣可以往下看,在文章最后贴上了仓库地址。项目采用前后端模式,前端使用 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. 用OpenMV自动识别颜色序列

    目录 用OpenMV自动识别颜色序列 用OpenMV自动识别颜色序列 新年假期过去啦~ 主控:OpenMV3 M7摄像头(STM32F765) IDE:OPENMV官方IDE 我将Capstone期间 ...

  2. Crontab在服务端进行设置定时执行任务

    Crontab简crontab是一个可以根据时间.日期.月份.星期的组合调度对重复任务的执行的守护进程.也可以讲Linux crontab是用来定期执行程序的命令. 当安装完成操作系统之后,默认便会启 ...

  3. DYOJ 【20220317模拟赛】瞬间移动 题解

    瞬间移动 题意 三维空间中从 \((0,0,0)\) 开始,每次移动 1,问刚好走 \(N\) 次能到 \((X,Y,Z)\) 的方案数 \(N\le10^7\),答案模 \(998244353\) ...

  4. 2020 CSP-J 初赛游记

    估分 预估 85 分,一是怕选错,而是最后真的错了一些 考点 排列组合:论临时抱佛脚的作用 靠前看了一下捆绑法和插板法,果然考了. 2.算法常识,和复杂度分析 冒泡排序最小交换次数 = n-1 , G ...

  5. 腾讯云数据库TDSQL-大咖论道 | 基础软件的过去、现在、未来

    近十年来,中国基础软件发展势头迅猛,市场前景看高,越来越多的企业也正在进行基础软件升级.那中国基础软件行业目前在国际市场上有什么优势,面临哪些困境,以及未来基础软件行业会如何发展呢?腾讯云数据库邀请沙 ...

  6. SpringBoot整合RabbitMQ实战附加死信交换机

    前言 使用springboot,实现以下功能,有两个队列1.2,往里面发送消息,如果处理失败发生异常,可以重试3次,重试3次均失败,那么就将消息发送到死信队列进行统一处理,例如记录数据库.报警等 环境 ...

  7. python亲密数设计

    '''亲密数 (如果a的所有正因子和等于b,b的所有正因子和等于a,因子包括1但不包括本身,且a不等于b,则称a,b为亲密数对.一般通过叠代编程求出相应的亲密数对)'''n = 3000def fun ...

  8. powershell命令总结

    2021-07-21 初稿 ps命令采用动词-名词的方式命名,不区分大小写.默认当前文件夹为当前路径./.除去-match使用正则表达式匹配外,其他都使用*和?通配符. 速查 管道命令 前一个的输出作 ...

  9. Skywalking光会用可不行,必须的源码分析分析 - Skywalking Agent &插件解析

    3 Skywalking源码导入 接上文,已经学习了Skywalking的应用,接下来我们将剖析Skywalking源码,深度学习Skywalking Agent. 3.1 源码环境搭建 当前最新版本 ...

  10. 数据库系列:MySQL索引优化总结(综合版)

    1 背景 作为一个常年在一线带组的Owner以及老面试官,我们面试的目标基本都是一线的开发人员.从服务端这个技术栈出发,问题的范围主要还是围绕开发语言(Java.Go)等核心知识点.数据库技术.缓存技 ...