在开始打造我们自己的实时聊天系统之前,我们需要先思考几个问题:
做过 IM 或信令的小伙伴都知道,实时传输对服务端有着颇高的要求。就以社交 APP 为例,每秒种要处理成百上千甚至更多的文字和图片的传输;弱网丢包的情况要保证消息的完整性的同时还要确保消息已送达;这其中的技术原理和解决方案不是一个 WebSocket所能涵盖的。
就消息必达而言,系统除了要有择优链路能力以外,还要具备多活链路。比如:一旦有一条链路出现问题,那么该消息就不一定能够送达。然而现实环境往往必我们想象中理想环境来的更糟糕和残酷,与此同时我们还要面对:网络丢包、用户量指数上升并发上不去,甚至系统宕机等等。
因此,要打造一个怎样的聊天系统,取决于我们产品的需求,根据需要选择集群部署的数量、节点的分布等诸多因素。
现在的社交 APP 玩法十分丰富,提供图文传输还加入了实时通讯模块,衍生出了直播连麦、主播 PK等诸多玩法,其中很大一部分都是通过自定义实时消息来完成。举个简单的例子:微信电话,A 给 B 发送一条带状态的消息、B 接收或者挂断操作之后,状态会被锁定之后无法变更,系统再将结果发送给 A,这个过程我们称之为呼叫邀请。
总之,实时消息不仅能带来通讯便利,同时还能辅助我们丰富我们的业务流程。
本项目 0 业务代码,因此只能通过指定几个固定的频道房间,来演示群组消息,大家如果有需要可以对接自己的业务系统替换项目中的随机头像、随机昵称、个性签名等数据;完善点对点消息、呼叫邀请等功能;同时还可以通过 RTM 的自定义消息进行广播处理更多复杂的情形。
源码请查看
使用 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```
为什么我们要选择 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 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 的用户发起呼叫邀请,在对方接收之后,双方加入同一个音视频通讯的房间,前提是项目需要集成音视频通讯的模块。