Giter Club home page Giter Club logo

js-realtime-sdk's Introduction

LeanCloud JavaScript Realtime SDK

npm npm gzip size Build Status Codecov Known Vulnerabilities

为您的 JavaScript App 接入 LeanCloud 实时通讯服务。

版本说明

遵循 语义化版本

安装稳定版本:

npm install leancloud-realtime --save

安装测试版本:

npm install leancloud-realtime@next --save

安装指定版本:

// 安装 v3 版本
npm install leancloud-realtime@3 --save

支持的运行环境

  • 浏览器 / WebView
    • IE 10+
    • Edge latest
    • Chrome 45+
    • Firefox latest
    • iOS 9.3+
    • Android 4.4+
  • Node.js 4.0+
  • 微信小程序/小游戏 latest
  • React Native 0.26+
  • Electron latest

文档

Demo

插件

package name 描述 版本 文档
leancloud-realtime-plugin-typed-messages 富媒体消息 npm API docs
leancloud-realtime-plugin-groupchat-receipts 群聊已读回执 npm API docs
leancloud-realtime-plugin-webrtc WebRTC 客户端 npm API docs

支持

  • 在使用过程中遇到了问题时
    • 如果你是商用版用户,请新建一个工单。
    • 也可以在 论坛 提问、讨论。

贡献

如果你希望为这个项目贡献代码,请按以下步骤进行:

  1. Fork 这个项目,clone 到本地
  2. 在目录中执行 npm install 安装所需 Node.js 依赖包
  3. 编码,更新测试用例
  4. 运行 npm test 确保测试全部 pass
  5. 提交改动,请遵循 conversational commit message 风格
  6. 发起 Pull Request 至 master 分支

项目的目录结构

.
├── demo
├── deploy.sh                 // 部署 gh-pages 分支
├── release.sh                // 部署 dist 分支
├── dist                      // 打包产出 (dist 分支)
│   ├── core.js               // 核心逻辑(不包含运行时)
│   ├── im.js                 // IM(不包含运行时)
│   ├── im-browser.js         // 浏览器用
│   ├── im-weapp.js           // 微信小程序用
│   └── im-node.js            // node 用
├── proto
│   ├── message-compiled.js     // 使用 pbjs 生成的 message 类
│   ├── message.js              // ES6 wrapper
│   └── message.proto           // proto 原始文件
├── src                       // 源码
│   └── index.js                // 打包入口
├── test                      // 测试用例
│   ├── browser                 // 浏览器测试入口
│   └── index.js                // 测试入口
└── plugins
    ├── typed-messages          // leancloud-realtime-plugin-typed-messages package
    └── webrtc                  // leancloud-realtime-plugin-webrtc package

Architecture

SDK 分为连接层与应用层两部分,只存在应用层对连接层公开 API 的调用,连接层对开发者不可见。

连接层

  • WebSocketPlus:封装了 WebSocket。相比 w3 WebSocket,增加了以下特性:
  • Connection:继承自 WebSocketPlus,增加了与业务相关的功能:
    • 根据 subprotocol 自动处理发送与接收的消息,应用层发送接收的均是 ProtoBuf Message 类
    • send 接口返回 Promise,在 server 回复后才算 send 成功
    • 实现了应用层 ping/pong

应用层

  • Realtime:开发者使用 SDK 的入口,负责访问 router、创建 connection、创建与管理 clients、创建 messageParser(管理消息类型)、监听 connection 的消息并 dispatch 给对应的 client
  • Client:所有的 clients 共享一个 connection
    • IMClient:对应即时通讯中的「用户」,持有 connection 与 conversations,负责创建管理将收到的消息处理后在对应 conversation 上派发,所有的 IMClients 共享一个 messageParser
  • MessageParser 消息解析器,负责将一个 JSON 格式的消息 parse 为对应的 Message 类
  • Conversation:实现对话相关的操作
    • ConversationQuery:对话查询器
  • Messages
    • AVMessage:接口描述,生成文档用
    • Message:消息基类
    • TypedMessage:类型消息基类,继承自 Message
    • TextMessage:文本消息,继承自 TypedMessage
    • 其他富媒体消息类(FileMessage 及其子类、LocationMessage)由于依赖 leancloud-storage,作为另一个独立 package 发布

开启调试模式

Node.js

export DEBUG=LC*

浏览器

localStorage.setItem('debug', 'LC*');

Develop Workflow

本地开发

更新 .proto 后请运行

npm run convert-pb

测试

npm run test:node -- --grep KEYWORDS

浏览器测试

npm run test:browser-local

编译

npm run build

持续集成

合并 PR 到 master 分支后持续集成会自动运行 npm buildnpm run docs,然后将 dist 目录推送到 dist 分支,将文档与 demo 推送到 gh-pages。

Release Process Workflow

  1. 遵循 semver 提升 package.json 中的版本号
  2. npm run changelog 生成新的 changelog.md,润色之
  3. Commit package.jsonchangelog.md
  4. Push to remote master branch
  5. 等待持续集成 pass
  6. 使用 GitHub 基于 dist 分支生成 pre-release 包(for bower)
  7. Fetch and checkout remote dist branch 并确认该提交的内容是即将发布的版本
  8. npm publish(npm publish,需 npm 协作者身份),如果是 pre-release 版本需要带 next tag
  9. 如有更新,在 npm 上发布各个 plugin

js-realtime-sdk's People

Contributors

dependabot[bot] avatar greenkeeperio-bot avatar hellolibo avatar hybrid-force avatar juvenn avatar jwfing avatar killme2008 avatar leeyeh avatar sdjdd avatar sunng87 avatar wangxiao avatar weakish avatar yujiangshui avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-realtime-sdk's Issues

room 的一些疑惑?

当前用户想和另一人对话时需要创建一个room,把自己和那个人一起加入, 聊了些内容后,过一段时间后,用户再次点开这个好友时,为了获取原来聊的内容,就必须要知道之间的room id,不然,又是新建room 了,那不是我还要想办法记录这个roomid?

README.md

var rtObject = lc.realtime({
   // appId 需要换成你自己的 appId
   appId: '9p6hyhh60av3ukkni3i9z53q1l8yy3cijj6sie3cewft18vm',
   // clientId 是自定义的名字,当前客户端可以理解的名字
   clientId: 'abc123'
   // auth 是权限校验的服务器地址,具体请看文档
   // auth: 'http://signature-example.avosapps.com/sign'
});
var room = rt.room('sasfalklkjdlfs123');

rt 是什么?

考虑 SDK 是否需要默认防止 XSS

@killme2008 @sunng87 @jwfing
实时聊天 SDK 使用过程中发现很多用户试了 XSS,如果是一般的小白用户可能就会忽略这个问题。
所以,是否 SDK 层面直接把 XSS 过滤默认做了?
如果用户有不做的需求,那我们有个配置,可以不做 XSS 转义,但是默认 SDK 层面是做 XSS 防御的。

应当始终抛出 Error 实例,而非字符串

SDK 对用户抛出的异常应当尽可能清晰地传达出发生的错误信息,现在有两点问题。

抛出的是字符串

抛出具体的 Error 实例会显示具体的 Error 类型,并附上调用堆栈,可以帮助用户更快地理解到底发什么了什么。两者区别如下图:

{
    ping: function() {
        // ...
        throw('Must call after open() has successed.');
    },
    room: function() {
        // ...
        throw new Error('Must call after open() has successed.');
    }
}

参考浏览器内建的几个 Error 类:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types

Error 信息太随意

Error 信息应该包含「发什么了什么错误」,可以给出「可能的原因及解决方案」。比如上面的 case 的错误文案可以更具体:「RealtimeObject.ping() called before the RealtimeObject.open() succeeded. RealtimeObject.ping() should be called in the callback of AV.realtime() or in a handler of 'open' event of RealtimeObject, see https://github.com/leancloud/js-realtime-sdk/blob/master/demo/demo1/test.js .」,这样可能对用户更有价值。

RealtimeObject.close()之后好像heartbeat依然在运行

close之后过一段时间会重复出现以下错误:

WebSocket is already in CLOSING or CLOSED state.      
wsSend                               AV.realtime.js:348
(anonymous function)                 AV.realtime.js:368 

感觉像是因为heartbeat还持续在运行。

另外目前有哪个函数可以获取RealtimeObject当前的状态吗(open,closed等)?

进入同一Room后的两个Peer,互相接收不到消息

            var onLogin = function (session) {

                rtObject = lc.realtime({
                    appId: '我的appId',
                    clientId: session.userId
                }, function () {
                    console.log('open');
                    rtObject.on('message', function (data) {
                        console.log(data);
                    });
                });

                rtObject.on('close', function () {
                    console.log('close');
                    console.log('reconnecting...');
                    rtObject.open();
                });
            };
            var enterRoom = function (roomId, receive) {

                    console.log('Entering room ' + roomId);

                    var r = rtObject.room(roomId);
                    r.receive(receive);

                    return {
                        send: function(msg) {
                            var deferred = $q.defer();
                            r.send(msg, function() {
                                deferred.resolve();
                            });
                            return deferred.promise;
                        }
                    };
                }

当调用send时,可以正常发出消息,inspect websocket frames也可以看到'ack',但是同一room内的其他peer却无法收到任何消息。上周末时还能正常收到消息,大约从前两天开始就不行了。请问这是什么原因?还是现在sdk不能正常工作?

有时一条消息会被收到多次

经测试,当某些情况发生(如网络状况不良等,无法100%复现)时,会发生同时有多个websocket链接in progress的情况。这个时候,当其它peer发来一条消息,本地的message事件会被调用多次。感觉像是connection被错误的判断为close,所以重新链接了?

send message 回调中的data 不应该是ack 命令

现在的是 ack:

image

    room.send({
        text: val
    }, {
        type: 'text'
    }, function (data) {

        // 发送成功之后的回调
        inputSend.value = '';
        showMsg(data);
        printWall.scrollTop = printWall.scrollHeight;
    });

上面 data 回调是 message 较好,这样可以统一处理,android 和 iOS 都是回调的 message。

@wangxiao

Invite or Join?

Hi, 我想请问一下目前roomObj.join的语义,究竟是invite还是join

以我目前的实验来看,sign请求发出时action写的是invite,请求中members有且只有一个id,就是用户自己。

单纯从这个roomObj.join的角度来说,这应该是一个join语义,但发出的却是invite请求。

这个奇怪的现象将直接影响后端sign的内部实现。

我认为这很可能是一个BUG。

增加内部 RoomObject 缓存

每次创建实例化一个 RoomObject 就存储在 cache 中,
用户如果获取相同的 RoomObject 直接返回 cache 中的,防止重复创建。

rt 的 "message" 事件的疑问?

文档中提到 “...收到的消息是当前客户端(clientId)存在的 Room 中的信息....” 这是不是意味着当初始化完成后,我必须为我所有的好友都建立room,不然,我是不是不能提收到他发来信息。

Review

记录 review 中一些问题

  • 命名空间
  • 创建 conv 是 id 是空字符串而非 null 的考虑是?
  • log 里的 setTimeout 可以去掉
  • 194行是否可能有数组越界
  • update callback 没有使用
  • 处理router返回404和403 的情况
  • startConv /remove 等函数的签名参数被注释掉了
  • tool.getId 返回一个自增整数即可,不要用字符串,未来可能会改成强类型

还没看完,明天可能会继续添加一些

调用RealtimeObject.close()导致ReferenceError

stack如下:

ReferenceError: options is not defined
    at Object.engine.closeSession (http://localhost:8888/assets/bower_components/leancloud-realtime/src/lc.realtime.js:485:20)
    at Object.newRealtimeObject.close (http://localhost:8888/assets/bower_components/leancloud-realtime/src/lc.realtime.js:944:24)
    at Object.$get.onLogin (http://localhost:8888/scripts/services/chatService.js:150:42)
    at http://localhost:8888/scripts/controllers/app/front/login.js:14:40
    at processQueue (http://localhost:8888/assets/bower_components/angular/angular.js:13248:27)
    at http://localhost:8888/assets/bower_components/angular/angular.js:13264:27
    at Scope.$get.Scope.$eval (http://localhost:8888/assets/bower_components/angular/angular.js:14466:28)
    at Scope.$get.Scope.$digest (http://localhost:8888/assets/bower_components/angular/angular.js:14282:31)
    at Scope.$get.Scope.$apply (http://localhost:8888/assets/bower_components/angular/angular.js:14571:24)
    at done (http://localhost:8888/assets/bower_components/angular/angular.js:9698:47)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.