Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

im-js/im.js

Repository files navigation

Im.JS

im-js-logo

一个基于 react-native + mobx + socket.io + node 的仿微信 JS-Wechat。
项目主页 Github-Im.JS

写在前面

Why Not JS ?
这是自己作为一个 JS 开发者面对来自他人的不确信,常常问起自己的问题。
我想不管答案是什么,更重要的是探索深挖的过程;不肤浅,总能有意想不到的收获。

效果图

iOS 预览 Android 请直接扫码下载体验
ios-demo.gif 安卓下载二维码

运行项目

react-native 在 debug 和 release 模式之间的性能差距是惊人的。

安装依赖

npm install

进入开发模式

react-native run-ios
// or
react-native run-android

Release 包生成
Running On Device
Generating Signed APK

基于 socket.io + koa2 + cloverx(自用 RestuFul 框架)

服务端用到了 cloverx-doc 从接口注释生成 Swagger 在线调试文档,还自带了一个输出格式化器,用来保证 Api 接口输出的一致性,纯手撸的,有兴趣可以看下。附一张效果图:

cloverx-doc-example

组件库

开发本项目的时候,要求自己尽量手写基础组件,基础组件与业务无关,可通用

组件库地址:UiLibrary

通过更改 app.json 的 appMode 字段,进行组件调试模式(UiLibrary)和 Im 模式(ImClient)的切换

开发笔记

TODO

接下来的开发重点在

  • socket 集群间通讯和管理(大量精力会在这里,还是服务器擅长一点)
  • 聊天室体验优化

计划中

  • 应用内离线消息,基于 Reids 实现。
  • Important [聊天室] 聊天室重构,使用 FlatListSectionList 替换 ListView
  • Important [聊天室] 优化加载历史消息下拉加载更多体验,实现连续滑屏。 Issue#1
  • Ack 消息触达、已读等状态回调。
  • 添加群聊支持
  • 公众号菜单以及对应后台 Dashboard 开发
  • 服务器升级为 httpswss

或许会做

  • 集成微信登录
  • 集成一个第三方推送服务

已知 Bug 列表

  • rnText 控件,即使指定 numberOfLines={1},消息如果以 \n 结尾,也会造成显示成 2 行。

技术文档

应用层消息事件和数据格式约定

Paylaod

基础定义

{
 from: String('用户ID'),
 to: String('用户ID'),
 uuid: String('消息唯一UUID'),
 // 用于存储消息内容
 msg: {
 ......
 },
 ext: {
 avatar: String('用户头像地址'),
 name: String('用户姓名'),
 // 可使用 moment().startOf('minute').fromNow() 格式化
 timestamp: timestamp(毫秒),
 },
 // 不参与网络传输,本地传递拓展字段位置
 localeExt: {
 ......
 }
}

msg 字段定义

对象必须包含如下字段

字段 定义 可选值
type 消息类型 txt

消息类型

// txt - 文本类型消息
{
 type: 'txt',
 content: '文本内容',
}

ext 字段定义

对象必须包含如下字段

字段 定义 可选值
timestamp 消息创建时间 UnixTimestamp(毫秒)

群聊与私聊

在消息传递层面,群聊和私聊共用一套事件机制,对于客户端来说,都是收到了某个用户的消息。

服务器层面,一个群的定义是 "业务逻辑圈定的一群用户",当一个 payload 的投递对象是一个群时, 服务器需要向这个群内的所有有效用户,发送 message 事件。

群聊的优化点在于,如何保证一个群内的用户尽可能多的在一个 socket 节点上,以此来降低 socket 节点间通讯的开销。

消息事件

Event: message

  • payloads: Array<Paylaod> - Payload 数组,新消息在数组尾部

客户端之间无法直接发送消息,需要由 socket 服务器转发。
客户端和服务端建立 socket 连接后,每个 emit, on 的对象都是远端,而非本地端。
客户端的所有 im 消息,都将通过监听 message 事件来接收。

交互时序如下:
message 交互时序图

Event: disconnect

发生在服务器和客户端之间的 socket 连接断开时。

这个事件将更改用户状态为 offline

Event: connection

  • socket - socket 连接对象

发生在服务器和客户端之间的 socket 连接建立、重连成功时。

Event: user:online

  • data: Object - 业务数据

当客户端存在登录用户信息且 socket 处于连接状态时,客户端向服务器发送用户上线事件。

im.js 设计中,data 中存放了如下信息,这个事件将更改用户的状态为 online

{
 userId: String('用户ID')
}

用户状态裁决

AppState 状态与 socket、用户在线状态关系。

State background inactive active
socket-ios close close connect
socket-android close \ connect
user-status offline offline online

离线消息机制

当用户状态为 offline 时候,触发离线消息机制。

im.js.server 的实现基于 Redis,单用户离线队列命名规则为 offline:queue:userId:${userId},存储结构为 Lists

当用户上线时候,客户端向服务器发送 user:online 事件,服务器以数组的形式返回对应用户的离线消息,并清空离线缓存。

ACK 处理

socket.emit(eventName[, ...args][, ack]) 提供了 Ack 回调。

此处 Ack 函数返回的状态,指的是单个 socket 连接两端点间消息是否送达成功,不代表对方用户是否收到(因为消息是由服务转发的)。

如果要做消息已读、是否送达等状态,需要在应用层继续做开发。

About

一个基于 react-native + mobx + socket.io + node 的仿微信 JS-Wechat

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /