实时聊天系统:一人一天一个可移植的Web技术分享

发表时间: 2021-11-02 12:24

在开始打造我们自己的实时聊天系统之前,我们需要先思考几个问题:

  • 用户体量大概多少?如何扩容?
  • 用户分布的区域?
  • 如何保证消息(低延时、必)送达?

做过 IM 或信令的小伙伴都知道,实时传输对服务端有着颇高的要求。就以社交 APP 为例,每秒种要处理成百上千甚至更多的文字和图片的传输;弱网丢包的情况要保证消息的完整性的同时还要确保消息已送达;这其中的技术原理和解决方案不是一个 WebSocket所能涵盖的。

就消息必达而言,系统除了要有择优链路能力以外,还要具备多活链路。比如:一旦有一条链路出现问题,那么该消息就不一定能够送达。然而现实环境往往必我们想象中理想环境来的更糟糕和残酷,与此同时我们还要面对:网络丢包用户量指数上升并发上不去,甚至系统宕机等等。

因此,要打造一个怎样的聊天系统,取决于我们产品的需求,根据需要选择集群部署的数量、节点的分布等诸多因素。

实时聊天系统应具备的特性

  • 高并发
  • 低延时
  • 消息必达
  • 弱网抗性
  • 集群部署
  • 消息推送(可选)

实时聊天系统应具备的功能

  • 点对点消息
  • 群组消息
  • 呼叫邀请

现在的社交 APP 玩法十分丰富,提供图文传输还加入了实时通讯模块,衍生出了直播连麦、主播 PK等诸多玩法,其中很大一部分都是通过自定义实时消息来完成。举个简单的例子:微信电话,A 给 B 发送一条带状态的消息、B 接收或者挂断操作之后,状态会被锁定之后无法变更,系统再将结果发送给 A,这个过程我们称之为呼叫邀请。

总之,实时消息不仅能带来通讯便利,同时还能辅助我们丰富我们的业务流程。

Vue3 + Tailwind + RTM = 实时聊天系统

项目说明

本项目 0 业务代码,因此只能通过指定几个固定的频道房间,来演示群组消息,大家如果有需要可以对接自己的业务系统替换项目中的随机头像、随机昵称、个性签名等数据;完善点对点消息呼叫邀请等功能;同时还可以通过 RTM 的自定义消息进行广播处理更多复杂的情形。

源码

源码请查看

  • [GitHub Demo](https://github.com/chudongvip/my-chat-demo)
  • [Gitee Demo](https://gitee.com/chudongvip/my-chat-demo)

使用 Vite 构建 Vue3 项目

使用 Vite构建一个 Vue3 项目,详情参考[官方文档](https://vitejs.cn/guide/#
%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA-vite-%E9%A1%B9%E7%9B%AE)。

创建项目

```# npm 6.xnpm init @vitejs/app my-chat-app --template vue# npm 7+, 需要额外的双横线:npm init @vitejs/app my-chat-app -- --template vue# yarnyarn create @vitejs/app my-chat-app --template vue```

安装依赖

```cd my-chat-appnpm installnpm run dev```

TailWind + TailWindComponents = UI

为什么我们要选择 tailwindcss

tailwindcss不仅节省了编写 css 的时间,还避免了命名烦恼,同时[tailwindComponents](
https://tailwindcomponents.com/) 提供了很多免费(使用 tailwind 开发)的
UI组件,我们可以从中找到一些现成的UI组件,何乐而不为呢?比如:下面是我们从[tailwindComponents](
https://tailwindcomponents.com/) 查找到的一些 [chat](
https://tailwindcomponents.com/search?query=chat) 相关的组件。

安装 tailwindcss

```npm install -D tailwindcss@latest postcss@latest autoprefixer@latest```

自动生成 tailwind 的配置文件

```npx tailwindcss init -p```

配置 tailwindcss

这里就不做代码的搬运工了,详情请参考[官方文档](
https://tailwindcss.com/docs/guides/vue-3-vite) ,中文请参考[中文文档](
https://www.tailwindcss.cn/docs/guides/vue-3-vite)。

集成 RTM 模块

项目使用的 [RTM SDK](
https://docs.anyrtc.io/cn/RealTimeMessage/quickstart/setup/messaging_web),相关 API 请查看[官方文档](
https://docs.anyrtc.io/cn/RealTimeMessage/api-ref/rtm_web/overview),大家可以根据需求替换。

安装 RTM

```npm install ar-rtm-sdk -D```

导入 RTM SDK

```import ArRTM from "ar-rtm-sdk"```

创建客户端

```const rtmClient = ArRTM.createInstance(Config.RTM_APP_ID, {	// 设置日志级别	logFilter: ArRTM.LOG_FILTER_OFF});```

登录 RTM 系统

```// 随机用户 ID,可以对接自己业务系统中的 UIDconst randomUserId = '' + Math.ceil(Math.random() * Math.pow(10, 10));const uid = await rtmClient.login({	uid: randomUserId});```

加入群组&监听群组消息回调

```// 创建群组const rtmChannel = rtmClient.createChannel(group.groupId);// 加入群组await rtmChannel.join();// 监听群组消息rtmChannel.on("ChannelMessage", (message, peerId, messagePros) => {	if (message.text) {		// 解析消息内容		const msgObj = JSON.parse(message.text);		// TODO...(例如,将消息显示到页面上)	}});```

根据业务拓展

  • 点对点消息

当对接业务系统后,可以使用业务中的 UID 作为 RTM 的 UID 登录,可以根据 UID 定向发送点对点消息。

  • 实时音视频通话

当对接业务系统后,可以向指定 UID 的用户发起呼叫邀请,在对方接收之后,双方加入同一个音视频通讯的房间,前提是项目需要集成音视频通讯的模块。