ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-08-20 15:03:13  阅读:154  来源: 互联网

标签:TypeScript Knex socket 私密 Room 私聊 服务器 string 客户端


前言

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

image

在本篇博文中,这一小节只是介绍 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 标识符,它是唯一的,且由服务器分配的。:

image

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

image

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

最后

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

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

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

标签:TypeScript,Knex,socket,私密,Room,私聊,服务器,string,客户端
来源: https://www.cnblogs.com/Enziandom/p/16607704.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有