├── publish.sh
├── .gitignore
├── bin
└── protoc
├── jest.config.js
├── src
├── packet.test.ts
├── proto.test.ts
├── login.ts
├── packet.ts
├── sdk.test.ts
├── proto
│ └── common.ts
└── sdk.ts
├── sdk
├── packet.test.js.map
├── proto.test.js
├── proto.test.js.map
├── login.js.map
├── packet.js.map
├── packet.test.js
├── packet.js
├── login.js
├── sdk.test.js.map
├── proto
│ ├── common.js.map
│ └── common.js
├── sdk.test.js
└── sdk.js.map
├── proto
├── common.proto
└── protocol.proto
├── package.json
├── README.md
├── index.ts
├── tsconfig.json
└── LICENSE
/publish.sh:
--------------------------------------------------------------------------------
1 | npm run build
2 | npm version patch
3 | npm publish
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .DS_Store
4 | .vscode
5 | index.js
--------------------------------------------------------------------------------
/bin/protoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klintcheng/kim_web_sdk/HEAD/bin/protoc
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('@ts-jest/dist/types').InitialOptionsTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'jsdom',
5 | };
--------------------------------------------------------------------------------
/src/packet.test.ts:
--------------------------------------------------------------------------------
1 | import { LoginReq } from "./proto/protocol"
2 | import { Command, LogicPkt, MagicLogicPktInt, print } from "./packet"
3 | import log from 'loglevel-es';
4 |
5 | log.setLevel("debug")
6 |
7 | test('logicpkt', async () => {
8 | const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk"
9 | let body = LoginReq.encode(LoginReq.fromJSON({
10 | token: token,
11 | })).finish()
12 | let loginReq = LogicPkt.build(Command.SignIn, "", body)
13 | let buf = loginReq.bytes()
14 | // 验证前面的4字节等于MagicLogicPktInt
15 | expect(buf.readInt32BE()).toEqual(MagicLogicPktInt)
16 | // 反序列化并验证之后的值是否与前面定义相同
17 | let pkt = LogicPkt.from(buf.subarray(4))
18 | expect(pkt.command).toEqual(Command.SignIn)
19 | expect(pkt.dest).toEqual("")
20 | expect(pkt.sequence).toBeGreaterThan(0)
21 | expect(pkt.payload.length).toEqual(body.length)
22 | // 验证payload消息体
23 | let req = LoginReq.decode(pkt.payload)
24 | expect(req.token).toEqual(token)
25 | })
26 |
--------------------------------------------------------------------------------
/sdk/packet.test.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"packet.test.js","sourceRoot":"","sources":["../src/packet.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA2C;AAC3C,mCAAqE;AACrE,4DAA8B;AAE9B,qBAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAErB,IAAI,CAAC,UAAU,EAAE;;;QACP,KAAK,GAAG,8IAA8I,CAAA;QACxJ,IAAI,GAAG,mBAAQ,CAAC,MAAM,CAAC,mBAAQ,CAAC,QAAQ,CAAC;YACzC,KAAK,EAAE,KAAK;SACf,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;QACR,QAAQ,GAAG,iBAAQ,CAAC,KAAK,CAAC,gBAAO,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;QACnD,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAA;QAC1B,6BAA6B;QAC7B,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAgB,CAAC,CAAA;QAE/C,GAAG,GAAG,iBAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,gBAAO,CAAC,MAAM,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC5B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAE3C,GAAG,GAAG,mBAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACtC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;;;KACnC,CAAC,CAAA"}
--------------------------------------------------------------------------------
/proto/common.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package pkt;
3 | option go_package = "./pkt";
4 |
5 | // status is a uint16 value
6 | enum Status {
7 | Success = 0;
8 | // client defined
9 |
10 | // client error 100-200
11 | NoDestination = 100;
12 | InvalidPacketBody = 101;
13 | InvalidCommand = 103;
14 | Unauthorized = 105 ;
15 | // server error 300-400
16 | SystemException = 300;
17 | NotImplemented = 301;
18 | //specific error
19 | SessionNotFound = 404; // session lost
20 | }
21 |
22 | enum MetaType {
23 | int = 0;
24 | string = 1;
25 | float = 2;
26 | }
27 |
28 | enum ContentType {
29 | Protobuf = 0;
30 | Json = 1;
31 | }
32 |
33 | enum Flag {
34 | Request = 0;
35 | Response = 1;
36 | Push = 2;
37 | }
38 |
39 | message Meta {
40 | string key = 1;
41 | string value = 2;
42 | MetaType type = 3;
43 | }
44 |
45 | message Header {
46 | string command = 1;
47 | // sender channel id
48 | string channelId = 2;
49 | uint32 sequence = 3;
50 | Flag flag = 4;
51 | Status status = 5;
52 | // destination is defined as a account,group or room
53 | string dest = 6;
54 | repeated Meta meta = 7;
55 | }
56 |
57 | message InnerHandshakeReq{
58 | string ServiceId = 1;
59 | }
60 |
61 | message InnerHandshakeResponse{
62 | uint32 Code = 1;
63 | string Error = 2;
64 | }
--------------------------------------------------------------------------------
/src/proto.test.ts:
--------------------------------------------------------------------------------
1 | import { MessagePush } from "./proto/protocol"
2 |
3 | test("msg_decode", () => {
4 | //messageId:1628644843872655000 type:1 body:"hello world" extra:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk"
5 | let arr = new Uint8Array([8, 152, 173, 180, 194, 180, 251, 134, 205, 22, 16, 1, 26, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 34, 140, 1, 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 73, 85, 122, 73, 49, 78, 105, 73, 115, 73, 110, 82, 53, 99, 67, 73, 54, 73, 107, 112, 88, 86, 67, 74, 57, 46, 101, 121, 74, 104, 89, 50, 77, 105, 79, 105, 74, 48, 90, 88, 78, 48, 77, 83, 73, 115, 73, 109, 70, 119, 99, 67, 73, 54, 73, 109, 116, 112, 98, 83, 73, 115, 73, 109, 86, 52, 99, 67, 73, 54, 77, 84, 89, 121, 79, 84, 65, 53, 77, 122, 85, 48, 79, 88, 48, 46, 80, 95, 121, 107, 49, 75, 77, 66, 53, 118, 57, 114, 105, 85, 121, 48, 121, 87, 52, 101, 79, 84, 103, 67, 48, 107, 48, 113, 101, 66, 54, 88, 82, 106, 105, 104, 52, 100, 76, 49, 120, 71, 107])
6 | let req = MessagePush.decode(arr)
7 | expect(req.messageId.toString()).toEqual("1628644843872655000")
8 | expect(req.body).toEqual("hello world")
9 | expect(req.extra).toEqual("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk")
10 | expect(req.type).toEqual(1)
11 | })
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kingim",
3 | "version": "1.1.0",
4 | "description": "king im sdk",
5 | "main": "index.ts",
6 | "scripts": {
7 | "test": "jest --verbose --force-exit ",
8 | "run": "ts-node index.ts",
9 | "build": "tsc"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/klintcheng/kim_web_sdk.git"
14 | },
15 | "keywords": [
16 | "im",
17 | "sdk"
18 | ],
19 | "author": "klintcheng",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/klintcheng/kim_web_sdk/issues"
23 | },
24 | "homepage": "https://github.com/klintcheng/kim_web_sdk#readme",
25 | "dependencies": {
26 | "@types/websocket": "^1.0.2",
27 | "buffer": "^6.0.3",
28 | "localforage": "^1.10.0",
29 | "loglevel-es": "^1.7.1",
30 | "websocket": "^1.0.34"
31 | },
32 | "devDependencies": {
33 | "@babel/core": "^7.15.0",
34 | "@babel/preset-env": "^7.15.0",
35 | "@babel/preset-typescript": "^7.15.0",
36 | "@types/jest": "^27.0.1",
37 | "babel-jest": "^27.0.6",
38 | "jest": "^27.0.6",
39 | "jest-localstorage-mock": "^2.4.16",
40 | "mock-local-storage": "^1.1.17",
41 | "ts-jest": "^27.0.4",
42 | "ts-node": "^10.2.0",
43 | "ts-proto": "^1.82.5",
44 | "typescript": "^4.3.5"
45 | },
46 | "jest": {
47 | "resetMocks": false,
48 | "setupFiles": [
49 | "jest-localstorage-mock"
50 | ]
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/sdk/proto.test.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | var protocol_1 = require("./proto/protocol");
4 | test("msg_decode", function () {
5 | //messageId:1628644843872655000 type:1 body:"hello world" extra:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk"
6 | var arr = new Uint8Array([8, 152, 173, 180, 194, 180, 251, 134, 205, 22, 16, 1, 26, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 34, 140, 1, 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 73, 85, 122, 73, 49, 78, 105, 73, 115, 73, 110, 82, 53, 99, 67, 73, 54, 73, 107, 112, 88, 86, 67, 74, 57, 46, 101, 121, 74, 104, 89, 50, 77, 105, 79, 105, 74, 48, 90, 88, 78, 48, 77, 83, 73, 115, 73, 109, 70, 119, 99, 67, 73, 54, 73, 109, 116, 112, 98, 83, 73, 115, 73, 109, 86, 52, 99, 67, 73, 54, 77, 84, 89, 121, 79, 84, 65, 53, 77, 122, 85, 48, 79, 88, 48, 46, 80, 95, 121, 107, 49, 75, 77, 66, 53, 118, 57, 114, 105, 85, 121, 48, 121, 87, 52, 101, 79, 84, 103, 67, 48, 107, 48, 113, 101, 66, 54, 88, 82, 106, 105, 104, 52, 100, 76, 49, 120, 71, 107]);
7 | var req = protocol_1.MessagePush.decode(arr);
8 | expect(req.messageId.toString()).toEqual("1628644843872655000");
9 | expect(req.body).toEqual("hello world");
10 | expect(req.extra).toEqual("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk");
11 | expect(req.type).toEqual(1);
12 | });
13 | //# sourceMappingURL=proto.test.js.map
--------------------------------------------------------------------------------
/sdk/proto.test.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"proto.test.js","sourceRoot":"","sources":["../src/proto.test.ts"],"names":[],"mappings":";;AAAA,6CAA8C;AAE9C,IAAI,CAAC,YAAY,EAAE;IACf,8MAA8M;IAC9M,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;IACtvB,IAAI,GAAG,GAAG,sBAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAC/D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IACvC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,8IAA8I,CAAC,CAAA;IACzK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAC/B,CAAC,CAAC,CAAA"}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # kim_web_sdk
2 |
3 | 本项目是King IM CLoud的web版本SDK。
4 |
5 | ## 安装
6 |
7 | > npm i kingim
8 |
9 | ## Quick Start
10 |
11 | 我们再次回顾下客户端的生命周期状态图,**在SDK端所有逻辑都离不开这个状态图**:
12 |
13 | 
14 |
15 | 一个简单的调用流程如下:
16 |
17 | ```ts
18 | const tags = ["web"]
19 | // 1. 初始化
20 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
21 |
22 | // 2. 注册监听器
23 | let evts = [KIMEvent.Closed, KIMEvent.Reconnecting, KIMEvent.Reconnected, KIMEvent.Kickout]
24 | cli.register(evts, eventcallback)
25 | cli.onmessage(messagecallback)
26 | cli.onofflinemessage(offmessagecallback)
27 |
28 | // 3. 登录
29 | let { success, err } = await cli.login()
30 | if (!success) {
31 | log.error(err)
32 | return
33 | }
34 |
35 | // 4. 发送消息
36 | let { status, resp, err: err2 } = await cli.talkToUser("test2", new Content("hello"))
37 | if (status != Status.Success) {
38 | log.error(err)
39 | return
40 | }
41 | log.info(`resp - ${resp?.messageId} ${resp?.sendTime.toString()}`)
42 |
43 | await sleep(10)
44 |
45 | // 5. 登出
46 | await cli.logout()
47 | ```
48 |
49 | **我们主要了解下其中三个监听器**:
50 |
51 | - **eventcallback**:事件监听器回调方法。在Client的生命周期图中,状态随着主动或被动的事件触发而发现改变。比如断线重连时两种状态`Reconnecting`和`Reconnected`,虽然SDK可能在几秒内就自动重连成功,但是这个变动过程还是要通知给上层,让业务决定是否显现给用户。
52 |
53 | ```ts
54 | let eventcallback = (evt: KIMEvent) => {
55 | log.info(`event ${evt}`)
56 | };
57 | ```
58 |
59 | - messagecallback:用于接收`在线消息`的回调方法。
60 |
61 | ```ts
62 | let messagecallback = (m: Message) => {
63 | log.info(m)
64 | }
65 | ```
66 |
67 | - offmessagecallback:`离线消息`回调方法。通常是**dologin**成功并且同步离线索引完成之后,才会回调给上层,如下是调用示例:
68 |
69 | ```ts
70 | let offmessagecallback = (om: OfflineMessages) => {
71 | // 离线时的发送方用户列表
72 | let users = om.listUsers()
73 | if (users.length > 0) {
74 | log.info(`offline messages from users of ${users}`)
75 | // lazy load the first page messages from 'users[0]'
76 | let messages = om.loadUser(users[0], 1)
77 | log.info(messages)
78 | }
79 | // 离线的群列表
80 | let groups = om.listGroups()
81 | if(groups.length > 0) {
82 | log.info(`offline messages from groups of ${groups}`)
83 | }
84 | }
85 | ```
86 |
87 | - `om.loadUser(users[0], 1)` 表示加载users[0]的第一页离线消息。
88 |
89 |
--------------------------------------------------------------------------------
/sdk/login.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | import { KIMClient, KIMEvent, Message, OfflineMessages, Content, sleep } from "./src/sdk";
2 | import log from 'loglevel-es';
3 | import 'mock-local-storage'
4 | import { Status } from "./src/proto/common";
5 |
6 | //三个测试账号 test1 ,test2 ,test3
7 | const tokens = [
8 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDQ4Nn0.YsjY42O9A1hIZaxgbgyUXjQul2RBmwFiAufdlZe3boo",
9 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MiIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDUxNX0.LnlacfRur79dyVnFAoYiGXTSwSiO__hHVnVm8B2f-IY",
10 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MyIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDYwOX0.VsBg31LfmgFwfbgHmHWK8u72PI4elAoz3K9p3oKq6EI",
11 | ]
12 |
13 | const gatewayURL = "ws://119.3.4.216:8000"
14 |
15 | log.setLevel("DEBUG")
16 |
17 | let main = async () => {
18 | const tags = ["web"]
19 | // 初始化
20 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
21 | let eventcallback = (evt: KIMEvent) => {
22 | log.info(`event ${evt}`)
23 | };
24 | let messagecallback = (m: Message) => {
25 | log.info(m)
26 | }
27 | let offmessagecallback = (om: OfflineMessages) => {
28 | // 离线时的发送方用户列表
29 | let users = om.listUsers()
30 | if (users.length > 0) {
31 | log.info(`offline messages from users of ${users}`)
32 | // lazy load the first page messages from 'users[0]'
33 | let messages = om.loadUser(users[0], 1)
34 | log.info(messages)
35 | }
36 | // 离线的群列表
37 | let groups = om.listGroups()
38 | if (groups.length > 0) {
39 | log.info(`offline messages from groups of ${groups}`)
40 | }
41 | }
42 | // 2.注册事件
43 | let evts = [KIMEvent.Closed, KIMEvent.Reconnecting, KIMEvent.Reconnected, KIMEvent.Kickout]
44 | cli.register(evts, eventcallback)
45 | cli.onmessage(messagecallback)
46 | cli.onofflinemessage(offmessagecallback)
47 | // 3. 登录
48 | let { success, err } = await cli.login()
49 | if (!success) {
50 | log.error(err)
51 | return
52 | }
53 |
54 | // 4. 发送消息
55 | let { status, resp, err: err2 } = await cli.talkToUser("test2", new Content("hello"))
56 | if (status != Status.Success) {
57 | log.error(err)
58 | return
59 | }
60 | log.info(`resp - ${resp?.messageId} ${resp?.sendTime.toString()}`)
61 |
62 | await sleep(10)
63 |
64 | // 5. 登出
65 | await cli.logout()
66 | }
67 |
68 | main()
--------------------------------------------------------------------------------
/src/login.ts:
--------------------------------------------------------------------------------
1 |
2 | import { w3cwebsocket } from 'websocket';
3 | import { Buffer } from 'buffer';
4 | import log from 'loglevel-es';
5 | import { Command, LogicPkt } from './packet';
6 | import { Status } from './proto/common';
7 | import { LoginReq, LoginResp } from './proto/protocol';
8 |
9 | const loginTimeout = 10 * 1000 // 10 seconds
10 |
11 | export class LoginBody {
12 | token: string;
13 | tags?: string[];
14 | constructor(token: string, tags?: string[]) {
15 | this.token = token;
16 | this.tags = tags;
17 | }
18 | }
19 |
20 | export let doLogin = async (url: string, req: LoginBody): Promise<{ success: boolean, err?: Error, channelId?: string, account?: string, conn: w3cwebsocket }> => {
21 | return new Promise((resolve, _) => {
22 | let conn = new w3cwebsocket(url)
23 | conn.binaryType = "arraybuffer"
24 |
25 | // 设置一个登陆超时器
26 | let tr = setTimeout(() => {
27 | clearTimeout(tr)
28 | resolve({ success: false, err: new Error("timeout"), conn: conn });
29 | }, loginTimeout);
30 |
31 | conn.onopen = () => {
32 | if (conn.readyState == w3cwebsocket.OPEN) {
33 | log.info(`connection established, send ${req.token}`)
34 | // send handshake request
35 | let pbreq = LoginReq.encode(LoginReq.fromJSON(req)).finish()
36 | let loginpkt = LogicPkt.build(Command.SignIn, "", pbreq)
37 | let buf = loginpkt.bytes()
38 | log.debug(`dologin send [${buf.join(",")}]`)
39 | conn.send(buf)
40 | }
41 | }
42 | conn.onerror = (error: Error) => {
43 | clearTimeout(tr)
44 | log.warn(error)
45 | resolve({ success: false, err: error, conn: conn });
46 | }
47 |
48 | conn.onmessage = (evt) => {
49 | if (typeof evt.data === 'string') {
50 | log.warn("Received: '" + evt.data + "'");
51 | return
52 | }
53 | clearTimeout(tr)
54 | // wating for login response
55 | let buf = Buffer.from(evt.data)
56 | let loginResp = LogicPkt.from(buf)
57 | if (loginResp.status != Status.Success) {
58 | log.error("Login failed: " + loginResp.status)
59 | resolve({ success: false, err: new Error(`response status is ${loginResp.status}`), conn: conn });
60 | return
61 | }
62 | let resp = LoginResp.decode(loginResp.payload)
63 | resolve({ success: true, channelId: resp.channelId, account: resp.account, conn: conn });
64 | }
65 |
66 | })
67 | }
68 |
--------------------------------------------------------------------------------
/proto/protocol.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package pkt;
3 | option go_package = "./pkt";
4 |
5 | message LoginReq {
6 | string token = 1;
7 | string isp = 2;
8 | string zone = 3; // location code
9 | repeated string tags = 4;
10 | }
11 |
12 | message LoginResp {
13 | string channelId = 1;
14 | string account = 2;
15 | }
16 |
17 | message KickoutNotify {
18 | string channelId = 1;
19 | }
20 |
21 | message Session {
22 | string channelId = 1;// session id
23 | string gateId = 2; // gateway ID
24 | string account = 3;
25 | string zone = 4;
26 | string isp = 5;
27 | string remoteIP = 6;
28 | string device = 7;
29 | string app = 8;
30 | repeated string tags = 9;
31 | }
32 |
33 | // chat message
34 | message MessageReq {
35 | int32 type = 1;
36 | string body = 2;
37 | string extra = 3;
38 | }
39 |
40 | message MessageResp {
41 | int64 messageId = 1;
42 | int64 sendTime = 2;
43 | }
44 |
45 | message MessagePush {
46 | int64 messageId = 1;
47 | int32 type = 2;
48 | string body = 3;
49 | string extra = 4;
50 | string sender = 5;
51 | int64 sendTime = 6;
52 | }
53 |
54 | message ErrorResp {
55 | string message= 1;
56 | }
57 |
58 | message MessageAckReq {
59 | int64 messageId = 1;
60 | }
61 |
62 | message GroupCreateReq {
63 | string name = 1;
64 | string avatar = 2;
65 | string introduction = 3;
66 | string owner = 4;
67 | repeated string members = 5;
68 | }
69 |
70 | message GroupCreateResp {
71 | string group_id = 1;
72 | }
73 |
74 | message GroupCreateNotify {
75 | string group_id = 1;
76 | repeated string members = 2;
77 | }
78 |
79 | message GroupJoinReq {
80 | string account = 1;
81 | string group_id = 2;
82 | }
83 |
84 | message GroupQuitReq {
85 | string account = 1;
86 | string group_id = 2;
87 | }
88 |
89 | message GroupGetReq {
90 | string group_id = 1;
91 | }
92 |
93 | message Member {
94 | string account = 1;
95 | string alias = 2;
96 | string avatar = 3;
97 | int64 join_time = 4;
98 | }
99 |
100 | message GroupGetResp {
101 | string id = 1;
102 | string name = 2;
103 | string avatar = 3;
104 | string introduction = 4;
105 | string owner = 5;
106 | repeated Member members = 6;
107 | int64 created_at = 7;
108 | }
109 |
110 | message GroupJoinNotify {
111 | string group_id = 1;
112 | string account = 2;
113 | }
114 |
115 | message GroupQuitNotify {
116 | string group_id = 1;
117 | string account = 2;
118 | }
119 |
120 | message MessageIndexReq {
121 | int64 message_id = 1;
122 | }
123 |
124 | message MessageIndexResp {
125 | repeated MessageIndex indexes = 1;
126 | }
127 |
128 | message MessageIndex {
129 | int64 message_id = 1;
130 | int32 direction = 2;
131 | int64 send_time = 3;
132 | string accountB = 4;
133 | string group = 5;
134 | }
135 |
136 | message MessageContentReq {
137 | repeated int64 message_ids = 1;
138 | }
139 |
140 | message MessageContent {
141 | int64 messageId = 1;
142 | int32 type = 2;
143 | string body = 3;
144 | string extra = 4;
145 | }
146 |
147 | message MessageContentResp {
148 | repeated MessageContent contents = 1;
149 | }
150 |
151 | // message Pkt {
152 | // uint32 Source = 1;
153 | // uint64 Sequence = 3;
154 | // bytes Data = 5;
155 | // }
--------------------------------------------------------------------------------
/sdk/packet.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"packet.js","sourceRoot":"","sources":["../src/packet.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/sdk/packet.test.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 | return new (P || (P = Promise))(function (resolve, reject) {
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
9 | });
10 | };
11 | var __generator = (this && this.__generator) || function (thisArg, body) {
12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14 | function verb(n) { return function (v) { return step([n, v]); }; }
15 | function step(op) {
16 | if (f) throw new TypeError("Generator is already executing.");
17 | while (_) try {
18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19 | if (y = 0, t) op = [op[0] & 2, t.value];
20 | switch (op[0]) {
21 | case 0: case 1: t = op; break;
22 | case 4: _.label++; return { value: op[1], done: false };
23 | case 5: _.label++; y = op[1]; op = [0]; continue;
24 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
25 | default:
26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30 | if (t[2]) _.ops.pop();
31 | _.trys.pop(); continue;
32 | }
33 | op = body.call(thisArg, _);
34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36 | }
37 | };
38 | var __importDefault = (this && this.__importDefault) || function (mod) {
39 | return (mod && mod.__esModule) ? mod : { "default": mod };
40 | };
41 | Object.defineProperty(exports, "__esModule", { value: true });
42 | var protocol_1 = require("./proto/protocol");
43 | var packet_1 = require("./packet");
44 | var loglevel_es_1 = __importDefault(require("loglevel-es"));
45 | loglevel_es_1.default.setLevel("debug");
46 | test('logicpkt', function () { return __awaiter(void 0, void 0, void 0, function () {
47 | var token, body, loginReq, buf, pkt, req;
48 | return __generator(this, function (_a) {
49 | token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTYyOTA5MzU0OX0.P_yk1KMB5v9riUy0yW4eOTgC0k0qeB6XRjih4dL1xGk";
50 | body = protocol_1.LoginReq.encode(protocol_1.LoginReq.fromJSON({
51 | token: token,
52 | })).finish();
53 | loginReq = packet_1.LogicPkt.build(packet_1.Command.SignIn, "", body);
54 | buf = loginReq.bytes();
55 | // 验证前面的4字节等于MagicLogicPktInt
56 | expect(buf.readInt32BE()).toEqual(packet_1.MagicLogicPktInt);
57 | pkt = packet_1.LogicPkt.from(buf.subarray(4));
58 | expect(pkt.command).toEqual(packet_1.Command.SignIn);
59 | expect(pkt.dest).toEqual("");
60 | expect(pkt.sequence).toBeGreaterThan(0);
61 | expect(pkt.payload.length).toEqual(body.length);
62 | req = protocol_1.LoginReq.decode(pkt.payload);
63 | expect(req.token).toEqual(token);
64 | return [2 /*return*/];
65 | });
66 | }); });
67 | //# sourceMappingURL=packet.test.js.map
--------------------------------------------------------------------------------
/src/packet.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Header, Flag, Status } from './proto/common';
3 | import log from 'loglevel-es';
4 |
5 | import * as buffer from "buffer";
6 |
7 | if (typeof (window as any).global === "undefined") {
8 | (window as any).global = window;
9 | }
10 | if (typeof (window as any).Buffer === "undefined") {
11 | (window as any).Buffer = buffer.Buffer;
12 | }
13 |
14 | export class Seq {
15 | static num: number = 0
16 | static Next() {
17 | Seq.num++
18 | Seq.num = Seq.num % 65536
19 | return Seq.num
20 | }
21 | }
22 |
23 | export enum Command {
24 | // login
25 | SignIn = "login.signin",
26 | SignOut = "login.signout",
27 |
28 | // chat
29 | ChatUserTalk = "chat.user.talk",
30 | ChatGroupTalk = "chat.group.talk",
31 | ChatTalkAck = "chat.talk.ack",
32 |
33 | // 离线
34 | OfflineIndex = "chat.offline.index",
35 | OfflineContent = "chat.offline.content",
36 |
37 | // 群管理
38 | GroupCreate = "chat.group.create",
39 | GroupJoin = "chat.group.join",
40 | GroupQuit = "chat.group.quit",
41 | GroupDetail = "chat.group.detail",
42 | }
43 |
44 | const MagicLogicPkt = new Uint8Array([0xc3, 0x11, 0xa3, 0x65])
45 | const MagicBasicPkt = new Uint8Array([0xc3, 0x15, 0xa7, 0x65])
46 |
47 | export const MagicLogicPktInt = Buffer.from(MagicLogicPkt).readInt32BE()
48 | export const MagicBasicPktInt = Buffer.from(MagicBasicPkt).readInt32BE()
49 |
50 | export enum MessageType {
51 | Text = 1, // 文本
52 | Image = 2, // 图片
53 | Voice = 3, // 语音
54 | Video = 4, //视频
55 | }
56 |
57 | export const Ping = new Uint8Array([0xc3, 0x15, 0xa7, 0x65, 0, 1, 0, 0])
58 | export const Pong = new Uint8Array([0xc3, 0x15, 0xa7, 0x65, 0, 2, 0, 0])
59 |
60 | export class LogicPkt {
61 | command?: string;
62 | channelId?: string;
63 | sequence: number = 0;
64 | flag?: number;
65 | status: number = Status.Success;
66 | dest?: string;
67 | payload: Uint8Array
68 | constructor() {
69 | this.payload = new Uint8Array();
70 | }
71 | static build(command: string, dest: string, payload: Uint8Array = new Uint8Array()): LogicPkt {
72 | // build LogicPkt
73 | let message = new LogicPkt()
74 | message.command = command
75 | message.sequence = Seq.Next()
76 | message.dest = dest
77 | if (payload.length > 0) {
78 | message.payload = payload
79 | }
80 | return message
81 | }
82 | static from(buf: Buffer): LogicPkt {
83 | let offset = 0
84 | let magic = buf.readInt32BE(offset)
85 | let hlen = 0
86 | // 判断前面四个字节是否为Magic
87 | if (magic == MagicLogicPktInt) {
88 | offset += 4
89 | }
90 | hlen = buf.readInt32BE(offset)
91 | offset += 4
92 | // 反序列化Header
93 | let header = Header.decode(buf.subarray(offset, offset + hlen))
94 | offset += hlen
95 | let message = new LogicPkt()
96 | // 把header中的属性copy到message
97 | Object.assign(message, header)
98 | // 读取payload
99 | let plen = buf.readInt32BE(offset)
100 | offset += 4
101 | message.payload = buf.subarray(offset, offset + plen)
102 | return message
103 | }
104 | bytes(): Buffer {
105 | let headerArray = Header.encode(Header.fromJSON(this)).finish()
106 | let hlen = headerArray.length
107 | let plen = this.payload.length
108 | //| 4bytes magic | 4bytes Header Length| header | 4bytes Payload Length| payload |
109 | let buf = Buffer.alloc(4 + 4 + hlen + 4 + plen)
110 | let offset = 0
111 | Buffer.from(MagicLogicPkt).copy(buf, offset, 0)
112 | offset += 4
113 | // 4bytes Header Length
114 | offset = buf.writeInt32BE(hlen, offset)
115 | // header
116 | Buffer.from(headerArray).copy(buf, offset, 0)
117 | offset += hlen
118 | // 4bytes Payload Length
119 | offset = buf.writeInt32BE(plen, offset)
120 | // payload
121 | Buffer.from(this.payload).copy(buf, offset, 0)
122 | return buf
123 | }
124 | }
125 |
126 | export let print = (arr: Uint8Array) => {
127 | if (arr == null) {
128 | return
129 | }
130 | console.info(`[${arr.join(",")}]`)
131 | }
--------------------------------------------------------------------------------
/sdk/packet.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.print = exports.LogicPkt = exports.Pong = exports.Ping = exports.MessageType = exports.MagicBasicPktInt = exports.MagicLogicPktInt = exports.Command = exports.Seq = void 0;
4 | var common_1 = require("./proto/common");
5 | var Seq = /** @class */ (function () {
6 | function Seq() {
7 | }
8 | Seq.Next = function () {
9 | Seq.num++;
10 | Seq.num = Seq.num % 65536;
11 | return Seq.num;
12 | };
13 | Seq.num = 0;
14 | return Seq;
15 | }());
16 | exports.Seq = Seq;
17 | var Command;
18 | (function (Command) {
19 | // login
20 | Command["SignIn"] = "login.signin";
21 | Command["SignOut"] = "login.signout";
22 | // chat
23 | Command["ChatUserTalk"] = "chat.user.talk";
24 | Command["ChatGroupTalk"] = "chat.group.talk";
25 | Command["ChatTalkAck"] = "chat.talk.ack";
26 | // 离线
27 | Command["OfflineIndex"] = "chat.offline.index";
28 | Command["OfflineContent"] = "chat.offline.content";
29 | // 群管理
30 | Command["GroupCreate"] = "chat.group.create";
31 | Command["GroupJoin"] = "chat.group.join";
32 | Command["GroupQuit"] = "chat.group.quit";
33 | Command["GroupDetail"] = "chat.group.detail";
34 | })(Command = exports.Command || (exports.Command = {}));
35 | var MagicLogicPkt = new Uint8Array([0xc3, 0x11, 0xa3, 0x65]);
36 | var MagicBasicPkt = new Uint8Array([0xc3, 0x15, 0xa7, 0x65]);
37 | exports.MagicLogicPktInt = Buffer.from(MagicLogicPkt).readInt32BE();
38 | exports.MagicBasicPktInt = Buffer.from(MagicBasicPkt).readInt32BE();
39 | var MessageType;
40 | (function (MessageType) {
41 | MessageType[MessageType["Text"] = 1] = "Text";
42 | MessageType[MessageType["Image"] = 2] = "Image";
43 | MessageType[MessageType["Voice"] = 3] = "Voice";
44 | MessageType[MessageType["Video"] = 4] = "Video";
45 | })(MessageType = exports.MessageType || (exports.MessageType = {}));
46 | exports.Ping = new Uint8Array([0xc3, 0x15, 0xa7, 0x65, 0, 1, 0, 0]);
47 | exports.Pong = new Uint8Array([0xc3, 0x15, 0xa7, 0x65, 0, 2, 0, 0]);
48 | var LogicPkt = /** @class */ (function () {
49 | function LogicPkt() {
50 | this.sequence = 0;
51 | this.status = common_1.Status.Success;
52 | this.payload = new Uint8Array();
53 | }
54 | LogicPkt.build = function (command, dest, payload) {
55 | if (payload === void 0) { payload = new Uint8Array(); }
56 | // build LogicPkt
57 | var message = new LogicPkt();
58 | message.command = command;
59 | message.sequence = Seq.Next();
60 | message.dest = dest;
61 | if (payload.length > 0) {
62 | message.payload = payload;
63 | }
64 | return message;
65 | };
66 | LogicPkt.from = function (buf) {
67 | var offset = 0;
68 | var magic = buf.readInt32BE(offset);
69 | var hlen = 0;
70 | // 判断前面四个字节是否为Magic
71 | if (magic == exports.MagicLogicPktInt) {
72 | offset += 4;
73 | }
74 | hlen = buf.readInt32BE(offset);
75 | offset += 4;
76 | // 反序列化Header
77 | var header = common_1.Header.decode(buf.subarray(offset, offset + hlen));
78 | offset += hlen;
79 | var message = new LogicPkt();
80 | // 把header中的属性copy到message
81 | Object.assign(message, header);
82 | // 读取payload
83 | var plen = buf.readInt32BE(offset);
84 | offset += 4;
85 | message.payload = buf.subarray(offset, offset + plen);
86 | return message;
87 | };
88 | LogicPkt.prototype.bytes = function () {
89 | var headerArray = common_1.Header.encode(common_1.Header.fromJSON(this)).finish();
90 | var hlen = headerArray.length;
91 | var plen = this.payload.length;
92 | //| 4bytes magic | 4bytes Header Length| header | 4bytes Payload Length| payload |
93 | var buf = Buffer.alloc(4 + 4 + hlen + 4 + plen);
94 | var offset = 0;
95 | Buffer.from(MagicLogicPkt).copy(buf, offset, 0);
96 | offset += 4;
97 | // 4bytes Header Length
98 | offset = buf.writeInt32BE(hlen, offset);
99 | // header
100 | Buffer.from(headerArray).copy(buf, offset, 0);
101 | offset += hlen;
102 | // 4bytes Payload Length
103 | offset = buf.writeInt32BE(plen, offset);
104 | // payload
105 | Buffer.from(this.payload).copy(buf, offset, 0);
106 | return buf;
107 | };
108 | return LogicPkt;
109 | }());
110 | exports.LogicPkt = LogicPkt;
111 | var print = function (arr) {
112 | if (arr == null) {
113 | return;
114 | }
115 | console.info("[" + arr.join(",") + "]");
116 | };
117 | exports.print = print;
118 | //# sourceMappingURL=packet.js.map
--------------------------------------------------------------------------------
/sdk/login.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 | return new (P || (P = Promise))(function (resolve, reject) {
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
9 | });
10 | };
11 | var __generator = (this && this.__generator) || function (thisArg, body) {
12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14 | function verb(n) { return function (v) { return step([n, v]); }; }
15 | function step(op) {
16 | if (f) throw new TypeError("Generator is already executing.");
17 | while (_) try {
18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19 | if (y = 0, t) op = [op[0] & 2, t.value];
20 | switch (op[0]) {
21 | case 0: case 1: t = op; break;
22 | case 4: _.label++; return { value: op[1], done: false };
23 | case 5: _.label++; y = op[1]; op = [0]; continue;
24 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
25 | default:
26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30 | if (t[2]) _.ops.pop();
31 | _.trys.pop(); continue;
32 | }
33 | op = body.call(thisArg, _);
34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36 | }
37 | };
38 | var __importDefault = (this && this.__importDefault) || function (mod) {
39 | return (mod && mod.__esModule) ? mod : { "default": mod };
40 | };
41 | Object.defineProperty(exports, "__esModule", { value: true });
42 | exports.doLogin = exports.LoginBody = void 0;
43 | var websocket_1 = require("websocket");
44 | var buffer_1 = require("buffer");
45 | var loglevel_es_1 = __importDefault(require("loglevel-es"));
46 | var packet_1 = require("./packet");
47 | var common_1 = require("./proto/common");
48 | var protocol_1 = require("./proto/protocol");
49 | var loginTimeout = 10 * 1000; // 10 seconds
50 | var LoginBody = /** @class */ (function () {
51 | function LoginBody(token, tags) {
52 | this.token = token;
53 | this.tags = tags;
54 | }
55 | return LoginBody;
56 | }());
57 | exports.LoginBody = LoginBody;
58 | var doLogin = function (url, req) { return __awaiter(void 0, void 0, void 0, function () {
59 | return __generator(this, function (_a) {
60 | return [2 /*return*/, new Promise(function (resolve, _) {
61 | var conn = new websocket_1.w3cwebsocket(url);
62 | conn.binaryType = "arraybuffer";
63 | // 设置一个登陆超时器
64 | var tr = setTimeout(function () {
65 | clearTimeout(tr);
66 | resolve({ success: false, err: new Error("timeout"), conn: conn });
67 | }, loginTimeout);
68 | conn.onopen = function () {
69 | if (conn.readyState == websocket_1.w3cwebsocket.OPEN) {
70 | loglevel_es_1.default.info("connection established, send " + req.token);
71 | // send handshake request
72 | var pbreq = protocol_1.LoginReq.encode(protocol_1.LoginReq.fromJSON(req)).finish();
73 | var loginpkt = packet_1.LogicPkt.build(packet_1.Command.SignIn, "", pbreq);
74 | var buf = loginpkt.bytes();
75 | loglevel_es_1.default.debug("dologin send [" + buf.join(",") + "]");
76 | conn.send(buf);
77 | }
78 | };
79 | conn.onerror = function (error) {
80 | clearTimeout(tr);
81 | loglevel_es_1.default.warn(error);
82 | resolve({ success: false, err: error, conn: conn });
83 | };
84 | conn.onmessage = function (evt) {
85 | if (typeof evt.data === 'string') {
86 | loglevel_es_1.default.warn("Received: '" + evt.data + "'");
87 | return;
88 | }
89 | clearTimeout(tr);
90 | // wating for login response
91 | var buf = buffer_1.Buffer.from(evt.data);
92 | var loginResp = packet_1.LogicPkt.from(buf);
93 | if (loginResp.status != common_1.Status.Success) {
94 | loglevel_es_1.default.error("Login failed: " + loginResp.status);
95 | resolve({ success: false, err: new Error("response status is " + loginResp.status), conn: conn });
96 | return;
97 | }
98 | var resp = protocol_1.LoginResp.decode(loginResp.payload);
99 | resolve({ success: true, channelId: resp.channelId, account: resp.account, conn: conn });
100 | };
101 | })];
102 | });
103 | }); };
104 | exports.doLogin = doLogin;
105 | //# sourceMappingURL=login.js.map
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 | /* Basic Options */
5 | // "incremental": true, /* Enable incremental compilation */
6 | "target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
7 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
8 | // "lib": [], /* Specify library files to be included in the compilation. */
9 | // "allowJs": true, /* Allow javascript files to be compiled. */
10 | // "checkJs": true, /* Report errors in .js files. */
11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
12 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
13 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
14 | "sourceMap": true, /* Generates corresponding '.map' file. */
15 | // "outFile": "./", /* Concatenate and emit output to single file. */
16 | "outDir": "./sdk/", /* Redirect output structure to the directory. */
17 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
18 | // "composite": true, /* Enable project compilation */
19 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
20 | // "removeComments": true, /* Do not emit comments to output. */
21 | // "noEmit": true, /* Do not emit outputs. */
22 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
23 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
24 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
25 | /* Strict Type-Checking Options */
26 | "strict": true, /* Enable all strict type-checking options. */
27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
28 | // "strictNullChecks": true, /* Enable strict null checks. */
29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
34 | /* Additional Checks */
35 | // "noUnusedLocals": true, /* Report errors on unused locals. */
36 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
37 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
38 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
39 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
40 | /* Module Resolution Options */
41 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
42 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
43 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
44 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
45 | // "typeRoots": [], /* List of folders to include type definitions from. */
46 | // "types": [], /* Type declaration files to be included in compilation. */
47 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
48 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
49 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
50 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
51 | /* Source Map Options */
52 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
53 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
54 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
55 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
56 | /* Experimental Options */
57 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
58 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
59 | /* Advanced Options */
60 | "skipLibCheck": true, /* Skip type checking of declaration files. */
61 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
62 | },
63 | "include": [
64 | "src/**/*"
65 | ],
66 | "exclude": [
67 | "node_modules",
68 | "proto",
69 | "bin"
70 | ]
71 | }
--------------------------------------------------------------------------------
/src/sdk.test.ts:
--------------------------------------------------------------------------------
1 | import { Content, KIMClient, KIMEvent, Store, Message, OfflineMessages, sleep } from "./sdk"
2 | import log from 'loglevel-es';
3 | import { doLogin } from "./login";
4 | import { Status } from "./proto/common";
5 | import { MessageType } from "./packet";
6 | import Long from 'long';
7 | import 'jest-localstorage-mock';
8 | log.setLevel("info")
9 | jest.setTimeout(30 * 1000)
10 |
11 | // https://jestjs.io/docs/cli
12 |
13 | //三个测试账号 test1 ,test2 ,test3
14 | const tokens = [
15 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDQ4Nn0.YsjY42O9A1hIZaxgbgyUXjQul2RBmwFiAufdlZe3boo",
16 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MiIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDUxNX0.LnlacfRur79dyVnFAoYiGXTSwSiO__hHVnVm8B2f-IY",
17 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MyIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDYwOX0.VsBg31LfmgFwfbgHmHWK8u72PI4elAoz3K9p3oKq6EI",
18 | ]
19 |
20 | const gatewayURL = "ws://119.3.4.216:8000"
21 |
22 | test('doLogin', async () => {
23 | const tags = ["web"]
24 | let { success, channelId, account, conn } = await doLogin(gatewayURL, { token: tokens[0], tags })
25 | expect(success).toBeTruthy()
26 | log.info(account, channelId)
27 | expect(channelId).toContain("test1")
28 | expect(account).toEqual("test1")
29 | conn.onclose = () => {
30 | log.info("closed")
31 | }
32 | conn.close()
33 | })
34 |
35 | test('doLoginfail', async () => {
36 | const tags = ["web"]
37 | let { success, err } = await doLogin(gatewayURL, { token: "", tags })
38 | expect(success).toBeFalsy()
39 | log.error(err)
40 | })
41 |
42 | test('store', async () => {
43 | let ok = await Store.insert(new Message(Long.fromNumber(1), Long.fromNumber(1)))
44 | expect(ok).toBeTruthy()
45 |
46 | let msg = await Store.get(Long.fromNumber(1))
47 | expect(msg?.messageId).toEqual(Long.fromNumber(1))
48 | log.info(msg)
49 | await Store.setAck(Long.fromNumber(1))
50 |
51 | let id = await Store.lastId()
52 | log.info("id - ", id)
53 | expect(id).toEqual(Long.fromNumber(1))
54 | })
55 |
56 | test('clilogin', async () => {
57 | // test1
58 | const tags = ["web"]
59 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
60 | let { success, err } = await cli.login()
61 | expect(success).toBeTruthy()
62 | let callback = jest.fn((evt: KIMEvent) => {
63 | log.info("--------", evt)
64 | });
65 | cli.register([KIMEvent.Closed], callback)
66 | expect(cli.account).toEqual("test1")
67 | await cli.logout()
68 | await sleep(2)
69 | // Closed回调方法必须被调用一次
70 | expect(callback).toBeCalledTimes(1)
71 | })
72 |
73 | test('dokickout', async () => {
74 | // test1
75 | const tags = ["web"]
76 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
77 | let { success, err } = await cli.login()
78 | expect(success).toBeTruthy()
79 | cli.register([KIMEvent.Kickout], (evt: KIMEvent) => {
80 | log.info("--------", evt)
81 | expect(evt).toEqual(KIMEvent.Kickout)
82 | })
83 |
84 | cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
85 | await cli.login()
86 | await sleep(1)
87 | await cli.logout()
88 | })
89 |
90 | test('usertalk', async () => {
91 | // test1
92 | const tags = ["web"]
93 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
94 | let { success, err } = await cli.login()
95 | expect(err).toBeUndefined()
96 | expect(success).toBeTruthy()
97 |
98 | let cli2 = new KIMClient(gatewayURL, { token: tokens[1], tags });
99 | let onmessage = jest.fn(async (m: Message) => {
100 | expect(m.sender).toEqual(cli.account)
101 | expect(m.receiver).toEqual(cli2.account)
102 | expect(m.body).toEqual("hello")
103 | expect(m.type).toEqual(MessageType.Text)
104 |
105 | await cli.logout()
106 | await cli2.logout()
107 | });
108 |
109 | cli2.onmessage(onmessage)
110 | let { success: suc } = await cli2.login()
111 | expect(suc).toBeTruthy()
112 | // { type: 1, body: "hello" }
113 | let { status, resp } = await cli.talkToUser(cli2.account, new Content("hello"))
114 | expect(status).toEqual(Status.Success)
115 | expect(resp?.messageId.greaterThan(1000)).toBeTruthy()
116 | expect(resp?.sendTime.greaterThan(1000)).toBeTruthy()
117 | await sleep(1)
118 | expect(onmessage).toBeCalledTimes(1)
119 | })
120 |
121 | test('offline', async () => {
122 | // test1
123 | const tags = ["web"]
124 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
125 | cli.onofflinemessage(async (om: OfflineMessages) => {
126 |
127 | })
128 | let { success, err } = await cli.login()
129 | expect(err).toBeUndefined()
130 | expect(success).toBeTruthy()
131 |
132 | // { type: 1, body: "hello" }
133 | let { status, resp, err: er } = await cli.talkToUser("test2", new Content("hello"))
134 | expect(status).toEqual(Status.Success)
135 | if (er) {
136 | log.error("---", er.message)
137 | }
138 | expect(resp?.messageId.greaterThan(1000)).toBeTruthy()
139 | expect(resp?.sendTime.greaterThan(1000)).toBeTruthy()
140 |
141 | let cli2 = new KIMClient(gatewayURL, { token: tokens[1], tags });
142 | let cb = jest.fn(async (om: OfflineMessages) => {
143 | let users = om.listUsers()
144 | log.info("onofflinemessage -- load ", users)
145 |
146 | expect(users.length).toBeGreaterThanOrEqual(1)
147 | log.info("--- lazy load messages")
148 | let msgs = await om.loadUser(users[0], 1)
149 | expect(msgs.length).toBeGreaterThanOrEqual(1)
150 | expect(msgs[0].body).toEqual("hello")
151 | // load again
152 | log.info("--- load again")
153 | msgs = await om.loadUser(users[0], 1)
154 | expect(msgs[0].body).toEqual("hello")
155 | await cli.logout()
156 | await cli2.logout()
157 | });
158 | cli2.onofflinemessage(cb)
159 | let { success: suc } = await cli2.login()
160 | expect(suc).toBeTruthy()
161 | expect(cb).toBeCalledTimes(1)
162 | await sleep(3)
163 | })
164 |
165 | test('group', async () => {
166 | // test1
167 | const tags = ["web"]
168 | let cli = new KIMClient(gatewayURL, { token: tokens[0], tags });
169 | let { success, err } = await cli.login()
170 | expect(err).toBeUndefined()
171 | expect(success).toBeTruthy()
172 |
173 | let resp = await cli.createGroup({
174 | name: "group_sdk",
175 | avatar: "",
176 | introduction: "test",
177 | members: ["test2"],
178 | })
179 | expect(resp.status).toEqual(Status.Success)
180 | expect(resp.resp?.groupId).not.toBeNull()
181 |
182 | let groupId = resp.resp?.groupId||""
183 | let resp2 = await cli.GetGroup({ groupId })
184 | expect(resp2.status).toEqual(Status.Success)
185 | expect(resp2.resp?.members.length).toEqual(2)
186 |
187 | let resp3 = await cli.joinGroup({ groupId, account: "test3" })
188 | expect(resp3.status).toEqual(Status.Success)
189 |
190 | let resp4 = await cli.GetGroup({ groupId })
191 | expect(resp4.status).toEqual(Status.Success)
192 | expect(resp4.resp?.members.length).toEqual(3)
193 | log.info(resp4)
194 |
195 | let resp5 = await cli.quitGroup({ groupId, account: "test3" })
196 | expect(resp5.status).toEqual(Status.Success)
197 |
198 | let resp6 = await cli.GetGroup({ groupId })
199 | expect(resp6.status).toEqual(Status.Success)
200 | expect(resp6.resp?.members.length).toEqual(2)
201 |
202 | await cli.logout()
203 | })
--------------------------------------------------------------------------------
/sdk/sdk.test.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"sdk.test.js","sourceRoot":"","sources":["../src/sdk.test.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/sdk/proto/common.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/proto/common.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/sdk/sdk.test.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 | return new (P || (P = Promise))(function (resolve, reject) {
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
9 | });
10 | };
11 | var __generator = (this && this.__generator) || function (thisArg, body) {
12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14 | function verb(n) { return function (v) { return step([n, v]); }; }
15 | function step(op) {
16 | if (f) throw new TypeError("Generator is already executing.");
17 | while (_) try {
18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19 | if (y = 0, t) op = [op[0] & 2, t.value];
20 | switch (op[0]) {
21 | case 0: case 1: t = op; break;
22 | case 4: _.label++; return { value: op[1], done: false };
23 | case 5: _.label++; y = op[1]; op = [0]; continue;
24 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
25 | default:
26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30 | if (t[2]) _.ops.pop();
31 | _.trys.pop(); continue;
32 | }
33 | op = body.call(thisArg, _);
34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36 | }
37 | };
38 | var __importDefault = (this && this.__importDefault) || function (mod) {
39 | return (mod && mod.__esModule) ? mod : { "default": mod };
40 | };
41 | Object.defineProperty(exports, "__esModule", { value: true });
42 | var sdk_1 = require("./sdk");
43 | var loglevel_es_1 = __importDefault(require("loglevel-es"));
44 | var login_1 = require("./login");
45 | var common_1 = require("./proto/common");
46 | var packet_1 = require("./packet");
47 | var long_1 = __importDefault(require("long"));
48 | require("jest-localstorage-mock");
49 | loglevel_es_1.default.setLevel("info");
50 | jest.setTimeout(30 * 1000);
51 | // https://jestjs.io/docs/cli
52 | //三个测试账号 test1 ,test2 ,test3
53 | var tokens = [
54 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MSIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDQ4Nn0.YsjY42O9A1hIZaxgbgyUXjQul2RBmwFiAufdlZe3boo",
55 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MiIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDUxNX0.LnlacfRur79dyVnFAoYiGXTSwSiO__hHVnVm8B2f-IY",
56 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2MiOiJ0ZXN0MyIsImFwcCI6ImtpbSIsImV4cCI6MTY2MDYzNDYwOX0.VsBg31LfmgFwfbgHmHWK8u72PI4elAoz3K9p3oKq6EI",
57 | ];
58 | var gatewayURL = "ws://119.3.4.216:8000";
59 | test('doLogin', function () { return __awaiter(void 0, void 0, void 0, function () {
60 | var tags, _a, success, channelId, account, conn;
61 | return __generator(this, function (_b) {
62 | switch (_b.label) {
63 | case 0:
64 | tags = ["web"];
65 | return [4 /*yield*/, login_1.doLogin(gatewayURL, { token: tokens[0], tags: tags })];
66 | case 1:
67 | _a = _b.sent(), success = _a.success, channelId = _a.channelId, account = _a.account, conn = _a.conn;
68 | expect(success).toBeTruthy();
69 | loglevel_es_1.default.info(account, channelId);
70 | expect(channelId).toContain("test1");
71 | expect(account).toEqual("test1");
72 | conn.onclose = function () {
73 | loglevel_es_1.default.info("closed");
74 | };
75 | conn.close();
76 | return [2 /*return*/];
77 | }
78 | });
79 | }); });
80 | test('doLoginfail', function () { return __awaiter(void 0, void 0, void 0, function () {
81 | var tags, _a, success, err;
82 | return __generator(this, function (_b) {
83 | switch (_b.label) {
84 | case 0:
85 | tags = ["web"];
86 | return [4 /*yield*/, login_1.doLogin(gatewayURL, { token: "", tags: tags })];
87 | case 1:
88 | _a = _b.sent(), success = _a.success, err = _a.err;
89 | expect(success).toBeFalsy();
90 | loglevel_es_1.default.error(err);
91 | return [2 /*return*/];
92 | }
93 | });
94 | }); });
95 | test('store', function () { return __awaiter(void 0, void 0, void 0, function () {
96 | var ok, msg, id;
97 | return __generator(this, function (_a) {
98 | switch (_a.label) {
99 | case 0: return [4 /*yield*/, sdk_1.Store.insert(new sdk_1.Message(long_1.default.fromNumber(1), long_1.default.fromNumber(1)))];
100 | case 1:
101 | ok = _a.sent();
102 | expect(ok).toBeTruthy();
103 | return [4 /*yield*/, sdk_1.Store.get(long_1.default.fromNumber(1))];
104 | case 2:
105 | msg = _a.sent();
106 | expect(msg === null || msg === void 0 ? void 0 : msg.messageId).toEqual(long_1.default.fromNumber(1));
107 | loglevel_es_1.default.info(msg);
108 | return [4 /*yield*/, sdk_1.Store.setAck(long_1.default.fromNumber(1))];
109 | case 3:
110 | _a.sent();
111 | return [4 /*yield*/, sdk_1.Store.lastId()];
112 | case 4:
113 | id = _a.sent();
114 | loglevel_es_1.default.info("id - ", id);
115 | expect(id).toEqual(long_1.default.fromNumber(1));
116 | return [2 /*return*/];
117 | }
118 | });
119 | }); });
120 | test('clilogin', function () { return __awaiter(void 0, void 0, void 0, function () {
121 | var tags, cli, _a, success, err, callback;
122 | return __generator(this, function (_b) {
123 | switch (_b.label) {
124 | case 0:
125 | tags = ["web"];
126 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
127 | return [4 /*yield*/, cli.login()];
128 | case 1:
129 | _a = _b.sent(), success = _a.success, err = _a.err;
130 | expect(success).toBeTruthy();
131 | callback = jest.fn(function (evt) {
132 | loglevel_es_1.default.info("--------", evt);
133 | });
134 | cli.register([sdk_1.KIMEvent.Closed], callback);
135 | expect(cli.account).toEqual("test1");
136 | return [4 /*yield*/, cli.logout()];
137 | case 2:
138 | _b.sent();
139 | return [4 /*yield*/, sdk_1.sleep(2)
140 | // Closed回调方法必须被调用一次
141 | ];
142 | case 3:
143 | _b.sent();
144 | // Closed回调方法必须被调用一次
145 | expect(callback).toBeCalledTimes(1);
146 | return [2 /*return*/];
147 | }
148 | });
149 | }); });
150 | test('dokickout', function () { return __awaiter(void 0, void 0, void 0, function () {
151 | var tags, cli, _a, success, err;
152 | return __generator(this, function (_b) {
153 | switch (_b.label) {
154 | case 0:
155 | tags = ["web"];
156 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
157 | return [4 /*yield*/, cli.login()];
158 | case 1:
159 | _a = _b.sent(), success = _a.success, err = _a.err;
160 | expect(success).toBeTruthy();
161 | cli.register([sdk_1.KIMEvent.Kickout], function (evt) {
162 | loglevel_es_1.default.info("--------", evt);
163 | expect(evt).toEqual(sdk_1.KIMEvent.Kickout);
164 | });
165 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
166 | return [4 /*yield*/, cli.login()];
167 | case 2:
168 | _b.sent();
169 | return [4 /*yield*/, sdk_1.sleep(1)];
170 | case 3:
171 | _b.sent();
172 | return [4 /*yield*/, cli.logout()];
173 | case 4:
174 | _b.sent();
175 | return [2 /*return*/];
176 | }
177 | });
178 | }); });
179 | test('usertalk', function () { return __awaiter(void 0, void 0, void 0, function () {
180 | var tags, cli, _a, success, err, cli2, onmessage, suc, _b, status, resp;
181 | return __generator(this, function (_c) {
182 | switch (_c.label) {
183 | case 0:
184 | tags = ["web"];
185 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
186 | return [4 /*yield*/, cli.login()];
187 | case 1:
188 | _a = _c.sent(), success = _a.success, err = _a.err;
189 | expect(err).toBeUndefined();
190 | expect(success).toBeTruthy();
191 | cli2 = new sdk_1.KIMClient(gatewayURL, { token: tokens[1], tags: tags });
192 | onmessage = jest.fn(function (m) { return __awaiter(void 0, void 0, void 0, function () {
193 | return __generator(this, function (_a) {
194 | switch (_a.label) {
195 | case 0:
196 | expect(m.sender).toEqual(cli.account);
197 | expect(m.receiver).toEqual(cli2.account);
198 | expect(m.body).toEqual("hello");
199 | expect(m.type).toEqual(packet_1.MessageType.Text);
200 | return [4 /*yield*/, cli.logout()];
201 | case 1:
202 | _a.sent();
203 | return [4 /*yield*/, cli2.logout()];
204 | case 2:
205 | _a.sent();
206 | return [2 /*return*/];
207 | }
208 | });
209 | }); });
210 | cli2.onmessage(onmessage);
211 | return [4 /*yield*/, cli2.login()];
212 | case 2:
213 | suc = (_c.sent()).success;
214 | expect(suc).toBeTruthy();
215 | return [4 /*yield*/, cli.talkToUser(cli2.account, new sdk_1.Content("hello"))];
216 | case 3:
217 | _b = _c.sent(), status = _b.status, resp = _b.resp;
218 | expect(status).toEqual(common_1.Status.Success);
219 | expect(resp === null || resp === void 0 ? void 0 : resp.messageId.greaterThan(1000)).toBeTruthy();
220 | expect(resp === null || resp === void 0 ? void 0 : resp.sendTime.greaterThan(1000)).toBeTruthy();
221 | return [4 /*yield*/, sdk_1.sleep(1)];
222 | case 4:
223 | _c.sent();
224 | expect(onmessage).toBeCalledTimes(1);
225 | return [2 /*return*/];
226 | }
227 | });
228 | }); });
229 | test('offline', function () { return __awaiter(void 0, void 0, void 0, function () {
230 | var tags, cli, _a, success, err, _b, status, resp, er, cli2, cb, suc;
231 | return __generator(this, function (_c) {
232 | switch (_c.label) {
233 | case 0:
234 | tags = ["web"];
235 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
236 | cli.onofflinemessage(function (om) { return __awaiter(void 0, void 0, void 0, function () {
237 | return __generator(this, function (_a) {
238 | return [2 /*return*/];
239 | });
240 | }); });
241 | return [4 /*yield*/, cli.login()];
242 | case 1:
243 | _a = _c.sent(), success = _a.success, err = _a.err;
244 | expect(err).toBeUndefined();
245 | expect(success).toBeTruthy();
246 | return [4 /*yield*/, cli.talkToUser("test2", new sdk_1.Content("hello"))];
247 | case 2:
248 | _b = _c.sent(), status = _b.status, resp = _b.resp, er = _b.err;
249 | expect(status).toEqual(common_1.Status.Success);
250 | if (er) {
251 | loglevel_es_1.default.error("---", er.message);
252 | }
253 | expect(resp === null || resp === void 0 ? void 0 : resp.messageId.greaterThan(1000)).toBeTruthy();
254 | expect(resp === null || resp === void 0 ? void 0 : resp.sendTime.greaterThan(1000)).toBeTruthy();
255 | cli2 = new sdk_1.KIMClient(gatewayURL, { token: tokens[1], tags: tags });
256 | cb = jest.fn(function (om) { return __awaiter(void 0, void 0, void 0, function () {
257 | var users, msgs;
258 | return __generator(this, function (_a) {
259 | switch (_a.label) {
260 | case 0:
261 | users = om.listUsers();
262 | loglevel_es_1.default.info("onofflinemessage -- load ", users);
263 | expect(users.length).toBeGreaterThanOrEqual(1);
264 | loglevel_es_1.default.info("--- lazy load messages");
265 | return [4 /*yield*/, om.loadUser(users[0], 1)];
266 | case 1:
267 | msgs = _a.sent();
268 | expect(msgs.length).toBeGreaterThanOrEqual(1);
269 | expect(msgs[0].body).toEqual("hello");
270 | // load again
271 | loglevel_es_1.default.info("--- load again");
272 | return [4 /*yield*/, om.loadUser(users[0], 1)];
273 | case 2:
274 | msgs = _a.sent();
275 | expect(msgs[0].body).toEqual("hello");
276 | return [4 /*yield*/, cli.logout()];
277 | case 3:
278 | _a.sent();
279 | return [4 /*yield*/, cli2.logout()];
280 | case 4:
281 | _a.sent();
282 | return [2 /*return*/];
283 | }
284 | });
285 | }); });
286 | cli2.onofflinemessage(cb);
287 | return [4 /*yield*/, cli2.login()];
288 | case 3:
289 | suc = (_c.sent()).success;
290 | expect(suc).toBeTruthy();
291 | expect(cb).toBeCalledTimes(1);
292 | return [4 /*yield*/, sdk_1.sleep(3)];
293 | case 4:
294 | _c.sent();
295 | return [2 /*return*/];
296 | }
297 | });
298 | }); });
299 | test('group', function () { return __awaiter(void 0, void 0, void 0, function () {
300 | var tags, cli, _a, success, err, resp, groupId, resp2, resp3, resp4, resp5, resp6;
301 | var _b, _c, _d, _e, _f;
302 | return __generator(this, function (_g) {
303 | switch (_g.label) {
304 | case 0:
305 | tags = ["web"];
306 | cli = new sdk_1.KIMClient(gatewayURL, { token: tokens[0], tags: tags });
307 | return [4 /*yield*/, cli.login()];
308 | case 1:
309 | _a = _g.sent(), success = _a.success, err = _a.err;
310 | expect(err).toBeUndefined();
311 | expect(success).toBeTruthy();
312 | return [4 /*yield*/, cli.createGroup({
313 | name: "group_sdk",
314 | avatar: "",
315 | introduction: "test",
316 | members: ["test2"],
317 | })];
318 | case 2:
319 | resp = _g.sent();
320 | expect(resp.status).toEqual(common_1.Status.Success);
321 | expect((_b = resp.resp) === null || _b === void 0 ? void 0 : _b.groupId).not.toBeNull();
322 | groupId = ((_c = resp.resp) === null || _c === void 0 ? void 0 : _c.groupId) || "";
323 | return [4 /*yield*/, cli.GetGroup({ groupId: groupId })];
324 | case 3:
325 | resp2 = _g.sent();
326 | expect(resp2.status).toEqual(common_1.Status.Success);
327 | expect((_d = resp2.resp) === null || _d === void 0 ? void 0 : _d.members.length).toEqual(2);
328 | return [4 /*yield*/, cli.joinGroup({ groupId: groupId, account: "test3" })];
329 | case 4:
330 | resp3 = _g.sent();
331 | expect(resp3.status).toEqual(common_1.Status.Success);
332 | return [4 /*yield*/, cli.GetGroup({ groupId: groupId })];
333 | case 5:
334 | resp4 = _g.sent();
335 | expect(resp4.status).toEqual(common_1.Status.Success);
336 | expect((_e = resp4.resp) === null || _e === void 0 ? void 0 : _e.members.length).toEqual(3);
337 | loglevel_es_1.default.info(resp4);
338 | return [4 /*yield*/, cli.quitGroup({ groupId: groupId, account: "test3" })];
339 | case 6:
340 | resp5 = _g.sent();
341 | expect(resp5.status).toEqual(common_1.Status.Success);
342 | return [4 /*yield*/, cli.GetGroup({ groupId: groupId })];
343 | case 7:
344 | resp6 = _g.sent();
345 | expect(resp6.status).toEqual(common_1.Status.Success);
346 | expect((_f = resp6.resp) === null || _f === void 0 ? void 0 : _f.members.length).toEqual(2);
347 | return [4 /*yield*/, cli.logout()];
348 | case 8:
349 | _g.sent();
350 | return [2 /*return*/];
351 | }
352 | });
353 | }); });
354 | //# sourceMappingURL=sdk.test.js.map
--------------------------------------------------------------------------------
/src/proto/common.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import Long from "long";
3 | import _m0 from "protobufjs/minimal";
4 |
5 | export const protobufPackage = "pkt";
6 |
7 | /** status is a uint16 value */
8 | export enum Status {
9 | /** Success - client defined */
10 | Success = 0,
11 | /** NoDestination - client error 100-200 */
12 | NoDestination = 100,
13 | InvalidPacketBody = 101,
14 | InvalidCommand = 103,
15 | Unauthorized = 105,
16 | /** SystemException - server error 300-400 */
17 | SystemException = 300,
18 | NotImplemented = 301,
19 | /** SessionNotFound - specific error */
20 | SessionNotFound = 404,
21 | UNRECOGNIZED = -1,
22 | }
23 |
24 | export function statusFromJSON(object: any): Status {
25 | switch (object) {
26 | case 0:
27 | case "Success":
28 | return Status.Success;
29 | case 100:
30 | case "NoDestination":
31 | return Status.NoDestination;
32 | case 101:
33 | case "InvalidPacketBody":
34 | return Status.InvalidPacketBody;
35 | case 103:
36 | case "InvalidCommand":
37 | return Status.InvalidCommand;
38 | case 105:
39 | case "Unauthorized":
40 | return Status.Unauthorized;
41 | case 300:
42 | case "SystemException":
43 | return Status.SystemException;
44 | case 301:
45 | case "NotImplemented":
46 | return Status.NotImplemented;
47 | case 404:
48 | case "SessionNotFound":
49 | return Status.SessionNotFound;
50 | case -1:
51 | case "UNRECOGNIZED":
52 | default:
53 | return Status.UNRECOGNIZED;
54 | }
55 | }
56 |
57 | export function statusToJSON(object: Status): string {
58 | switch (object) {
59 | case Status.Success:
60 | return "Success";
61 | case Status.NoDestination:
62 | return "NoDestination";
63 | case Status.InvalidPacketBody:
64 | return "InvalidPacketBody";
65 | case Status.InvalidCommand:
66 | return "InvalidCommand";
67 | case Status.Unauthorized:
68 | return "Unauthorized";
69 | case Status.SystemException:
70 | return "SystemException";
71 | case Status.NotImplemented:
72 | return "NotImplemented";
73 | case Status.SessionNotFound:
74 | return "SessionNotFound";
75 | default:
76 | return "UNKNOWN";
77 | }
78 | }
79 |
80 | export enum MetaType {
81 | int = 0,
82 | string = 1,
83 | float = 2,
84 | UNRECOGNIZED = -1,
85 | }
86 |
87 | export function metaTypeFromJSON(object: any): MetaType {
88 | switch (object) {
89 | case 0:
90 | case "int":
91 | return MetaType.int;
92 | case 1:
93 | case "string":
94 | return MetaType.string;
95 | case 2:
96 | case "float":
97 | return MetaType.float;
98 | case -1:
99 | case "UNRECOGNIZED":
100 | default:
101 | return MetaType.UNRECOGNIZED;
102 | }
103 | }
104 |
105 | export function metaTypeToJSON(object: MetaType): string {
106 | switch (object) {
107 | case MetaType.int:
108 | return "int";
109 | case MetaType.string:
110 | return "string";
111 | case MetaType.float:
112 | return "float";
113 | default:
114 | return "UNKNOWN";
115 | }
116 | }
117 |
118 | export enum ContentType {
119 | Protobuf = 0,
120 | Json = 1,
121 | UNRECOGNIZED = -1,
122 | }
123 |
124 | export function contentTypeFromJSON(object: any): ContentType {
125 | switch (object) {
126 | case 0:
127 | case "Protobuf":
128 | return ContentType.Protobuf;
129 | case 1:
130 | case "Json":
131 | return ContentType.Json;
132 | case -1:
133 | case "UNRECOGNIZED":
134 | default:
135 | return ContentType.UNRECOGNIZED;
136 | }
137 | }
138 |
139 | export function contentTypeToJSON(object: ContentType): string {
140 | switch (object) {
141 | case ContentType.Protobuf:
142 | return "Protobuf";
143 | case ContentType.Json:
144 | return "Json";
145 | default:
146 | return "UNKNOWN";
147 | }
148 | }
149 |
150 | export enum Flag {
151 | Request = 0,
152 | Response = 1,
153 | Push = 2,
154 | UNRECOGNIZED = -1,
155 | }
156 |
157 | export function flagFromJSON(object: any): Flag {
158 | switch (object) {
159 | case 0:
160 | case "Request":
161 | return Flag.Request;
162 | case 1:
163 | case "Response":
164 | return Flag.Response;
165 | case 2:
166 | case "Push":
167 | return Flag.Push;
168 | case -1:
169 | case "UNRECOGNIZED":
170 | default:
171 | return Flag.UNRECOGNIZED;
172 | }
173 | }
174 |
175 | export function flagToJSON(object: Flag): string {
176 | switch (object) {
177 | case Flag.Request:
178 | return "Request";
179 | case Flag.Response:
180 | return "Response";
181 | case Flag.Push:
182 | return "Push";
183 | default:
184 | return "UNKNOWN";
185 | }
186 | }
187 |
188 | export interface Meta {
189 | key: string;
190 | value: string;
191 | type: MetaType;
192 | }
193 |
194 | export interface Header {
195 | command: string;
196 | /** sender channel id */
197 | channelId: string;
198 | sequence: number;
199 | flag: Flag;
200 | status: Status;
201 | /** destination is defined as a account,group or room */
202 | dest: string;
203 | meta: Meta[];
204 | }
205 |
206 | export interface InnerHandshakeReq {
207 | ServiceId: string;
208 | }
209 |
210 | export interface InnerHandshakeResponse {
211 | Code: number;
212 | Error: string;
213 | }
214 |
215 | const baseMeta: object = { key: "", value: "", type: 0 };
216 |
217 | export const Meta = {
218 | encode(message: Meta, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
219 | if (message.key !== "") {
220 | writer.uint32(10).string(message.key);
221 | }
222 | if (message.value !== "") {
223 | writer.uint32(18).string(message.value);
224 | }
225 | if (message.type !== 0) {
226 | writer.uint32(24).int32(message.type);
227 | }
228 | return writer;
229 | },
230 |
231 | decode(input: _m0.Reader | Uint8Array, length?: number): Meta {
232 | const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
233 | let end = length === undefined ? reader.len : reader.pos + length;
234 | const message = { ...baseMeta } as Meta;
235 | while (reader.pos < end) {
236 | const tag = reader.uint32();
237 | switch (tag >>> 3) {
238 | case 1:
239 | message.key = reader.string();
240 | break;
241 | case 2:
242 | message.value = reader.string();
243 | break;
244 | case 3:
245 | message.type = reader.int32() as any;
246 | break;
247 | default:
248 | reader.skipType(tag & 7);
249 | break;
250 | }
251 | }
252 | return message;
253 | },
254 |
255 | fromJSON(object: any): Meta {
256 | const message = { ...baseMeta } as Meta;
257 | if (object.key !== undefined && object.key !== null) {
258 | message.key = String(object.key);
259 | } else {
260 | message.key = "";
261 | }
262 | if (object.value !== undefined && object.value !== null) {
263 | message.value = String(object.value);
264 | } else {
265 | message.value = "";
266 | }
267 | if (object.type !== undefined && object.type !== null) {
268 | message.type = metaTypeFromJSON(object.type);
269 | } else {
270 | message.type = 0;
271 | }
272 | return message;
273 | },
274 |
275 | toJSON(message: Meta): unknown {
276 | const obj: any = {};
277 | message.key !== undefined && (obj.key = message.key);
278 | message.value !== undefined && (obj.value = message.value);
279 | message.type !== undefined && (obj.type = metaTypeToJSON(message.type));
280 | return obj;
281 | },
282 |
283 | fromPartial(object: DeepPartial): Meta {
284 | const message = { ...baseMeta } as Meta;
285 | if (object.key !== undefined && object.key !== null) {
286 | message.key = object.key;
287 | } else {
288 | message.key = "";
289 | }
290 | if (object.value !== undefined && object.value !== null) {
291 | message.value = object.value;
292 | } else {
293 | message.value = "";
294 | }
295 | if (object.type !== undefined && object.type !== null) {
296 | message.type = object.type;
297 | } else {
298 | message.type = 0;
299 | }
300 | return message;
301 | },
302 | };
303 |
304 | const baseHeader: object = {
305 | command: "",
306 | channelId: "",
307 | sequence: 0,
308 | flag: 0,
309 | status: 0,
310 | dest: "",
311 | };
312 |
313 | export const Header = {
314 | encode(
315 | message: Header,
316 | writer: _m0.Writer = _m0.Writer.create()
317 | ): _m0.Writer {
318 | if (message.command !== "") {
319 | writer.uint32(10).string(message.command);
320 | }
321 | if (message.channelId !== "") {
322 | writer.uint32(18).string(message.channelId);
323 | }
324 | if (message.sequence !== 0) {
325 | writer.uint32(24).uint32(message.sequence);
326 | }
327 | if (message.flag !== 0) {
328 | writer.uint32(32).int32(message.flag);
329 | }
330 | if (message.status !== 0) {
331 | writer.uint32(40).int32(message.status);
332 | }
333 | if (message.dest !== "") {
334 | writer.uint32(50).string(message.dest);
335 | }
336 | for (const v of message.meta) {
337 | Meta.encode(v!, writer.uint32(58).fork()).ldelim();
338 | }
339 | return writer;
340 | },
341 |
342 | decode(input: _m0.Reader | Uint8Array, length?: number): Header {
343 | const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
344 | let end = length === undefined ? reader.len : reader.pos + length;
345 | const message = { ...baseHeader } as Header;
346 | message.meta = [];
347 | while (reader.pos < end) {
348 | const tag = reader.uint32();
349 | switch (tag >>> 3) {
350 | case 1:
351 | message.command = reader.string();
352 | break;
353 | case 2:
354 | message.channelId = reader.string();
355 | break;
356 | case 3:
357 | message.sequence = reader.uint32();
358 | break;
359 | case 4:
360 | message.flag = reader.int32() as any;
361 | break;
362 | case 5:
363 | message.status = reader.int32() as any;
364 | break;
365 | case 6:
366 | message.dest = reader.string();
367 | break;
368 | case 7:
369 | message.meta.push(Meta.decode(reader, reader.uint32()));
370 | break;
371 | default:
372 | reader.skipType(tag & 7);
373 | break;
374 | }
375 | }
376 | return message;
377 | },
378 |
379 | fromJSON(object: any): Header {
380 | const message = { ...baseHeader } as Header;
381 | message.meta = [];
382 | if (object.command !== undefined && object.command !== null) {
383 | message.command = String(object.command);
384 | } else {
385 | message.command = "";
386 | }
387 | if (object.channelId !== undefined && object.channelId !== null) {
388 | message.channelId = String(object.channelId);
389 | } else {
390 | message.channelId = "";
391 | }
392 | if (object.sequence !== undefined && object.sequence !== null) {
393 | message.sequence = Number(object.sequence);
394 | } else {
395 | message.sequence = 0;
396 | }
397 | if (object.flag !== undefined && object.flag !== null) {
398 | message.flag = flagFromJSON(object.flag);
399 | } else {
400 | message.flag = 0;
401 | }
402 | if (object.status !== undefined && object.status !== null) {
403 | message.status = statusFromJSON(object.status);
404 | } else {
405 | message.status = 0;
406 | }
407 | if (object.dest !== undefined && object.dest !== null) {
408 | message.dest = String(object.dest);
409 | } else {
410 | message.dest = "";
411 | }
412 | if (object.meta !== undefined && object.meta !== null) {
413 | for (const e of object.meta) {
414 | message.meta.push(Meta.fromJSON(e));
415 | }
416 | }
417 | return message;
418 | },
419 |
420 | toJSON(message: Header): unknown {
421 | const obj: any = {};
422 | message.command !== undefined && (obj.command = message.command);
423 | message.channelId !== undefined && (obj.channelId = message.channelId);
424 | message.sequence !== undefined && (obj.sequence = message.sequence);
425 | message.flag !== undefined && (obj.flag = flagToJSON(message.flag));
426 | message.status !== undefined && (obj.status = statusToJSON(message.status));
427 | message.dest !== undefined && (obj.dest = message.dest);
428 | if (message.meta) {
429 | obj.meta = message.meta.map((e) => (e ? Meta.toJSON(e) : undefined));
430 | } else {
431 | obj.meta = [];
432 | }
433 | return obj;
434 | },
435 |
436 | fromPartial(object: DeepPartial): Header {
437 | const message = { ...baseHeader } as Header;
438 | message.meta = [];
439 | if (object.command !== undefined && object.command !== null) {
440 | message.command = object.command;
441 | } else {
442 | message.command = "";
443 | }
444 | if (object.channelId !== undefined && object.channelId !== null) {
445 | message.channelId = object.channelId;
446 | } else {
447 | message.channelId = "";
448 | }
449 | if (object.sequence !== undefined && object.sequence !== null) {
450 | message.sequence = object.sequence;
451 | } else {
452 | message.sequence = 0;
453 | }
454 | if (object.flag !== undefined && object.flag !== null) {
455 | message.flag = object.flag;
456 | } else {
457 | message.flag = 0;
458 | }
459 | if (object.status !== undefined && object.status !== null) {
460 | message.status = object.status;
461 | } else {
462 | message.status = 0;
463 | }
464 | if (object.dest !== undefined && object.dest !== null) {
465 | message.dest = object.dest;
466 | } else {
467 | message.dest = "";
468 | }
469 | if (object.meta !== undefined && object.meta !== null) {
470 | for (const e of object.meta) {
471 | message.meta.push(Meta.fromPartial(e));
472 | }
473 | }
474 | return message;
475 | },
476 | };
477 |
478 | const baseInnerHandshakeReq: object = { ServiceId: "" };
479 |
480 | export const InnerHandshakeReq = {
481 | encode(
482 | message: InnerHandshakeReq,
483 | writer: _m0.Writer = _m0.Writer.create()
484 | ): _m0.Writer {
485 | if (message.ServiceId !== "") {
486 | writer.uint32(10).string(message.ServiceId);
487 | }
488 | return writer;
489 | },
490 |
491 | decode(input: _m0.Reader | Uint8Array, length?: number): InnerHandshakeReq {
492 | const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
493 | let end = length === undefined ? reader.len : reader.pos + length;
494 | const message = { ...baseInnerHandshakeReq } as InnerHandshakeReq;
495 | while (reader.pos < end) {
496 | const tag = reader.uint32();
497 | switch (tag >>> 3) {
498 | case 1:
499 | message.ServiceId = reader.string();
500 | break;
501 | default:
502 | reader.skipType(tag & 7);
503 | break;
504 | }
505 | }
506 | return message;
507 | },
508 |
509 | fromJSON(object: any): InnerHandshakeReq {
510 | const message = { ...baseInnerHandshakeReq } as InnerHandshakeReq;
511 | if (object.ServiceId !== undefined && object.ServiceId !== null) {
512 | message.ServiceId = String(object.ServiceId);
513 | } else {
514 | message.ServiceId = "";
515 | }
516 | return message;
517 | },
518 |
519 | toJSON(message: InnerHandshakeReq): unknown {
520 | const obj: any = {};
521 | message.ServiceId !== undefined && (obj.ServiceId = message.ServiceId);
522 | return obj;
523 | },
524 |
525 | fromPartial(object: DeepPartial): InnerHandshakeReq {
526 | const message = { ...baseInnerHandshakeReq } as InnerHandshakeReq;
527 | if (object.ServiceId !== undefined && object.ServiceId !== null) {
528 | message.ServiceId = object.ServiceId;
529 | } else {
530 | message.ServiceId = "";
531 | }
532 | return message;
533 | },
534 | };
535 |
536 | const baseInnerHandshakeResponse: object = { Code: 0, Error: "" };
537 |
538 | export const InnerHandshakeResponse = {
539 | encode(
540 | message: InnerHandshakeResponse,
541 | writer: _m0.Writer = _m0.Writer.create()
542 | ): _m0.Writer {
543 | if (message.Code !== 0) {
544 | writer.uint32(8).uint32(message.Code);
545 | }
546 | if (message.Error !== "") {
547 | writer.uint32(18).string(message.Error);
548 | }
549 | return writer;
550 | },
551 |
552 | decode(
553 | input: _m0.Reader | Uint8Array,
554 | length?: number
555 | ): InnerHandshakeResponse {
556 | const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
557 | let end = length === undefined ? reader.len : reader.pos + length;
558 | const message = { ...baseInnerHandshakeResponse } as InnerHandshakeResponse;
559 | while (reader.pos < end) {
560 | const tag = reader.uint32();
561 | switch (tag >>> 3) {
562 | case 1:
563 | message.Code = reader.uint32();
564 | break;
565 | case 2:
566 | message.Error = reader.string();
567 | break;
568 | default:
569 | reader.skipType(tag & 7);
570 | break;
571 | }
572 | }
573 | return message;
574 | },
575 |
576 | fromJSON(object: any): InnerHandshakeResponse {
577 | const message = { ...baseInnerHandshakeResponse } as InnerHandshakeResponse;
578 | if (object.Code !== undefined && object.Code !== null) {
579 | message.Code = Number(object.Code);
580 | } else {
581 | message.Code = 0;
582 | }
583 | if (object.Error !== undefined && object.Error !== null) {
584 | message.Error = String(object.Error);
585 | } else {
586 | message.Error = "";
587 | }
588 | return message;
589 | },
590 |
591 | toJSON(message: InnerHandshakeResponse): unknown {
592 | const obj: any = {};
593 | message.Code !== undefined && (obj.Code = message.Code);
594 | message.Error !== undefined && (obj.Error = message.Error);
595 | return obj;
596 | },
597 |
598 | fromPartial(
599 | object: DeepPartial
600 | ): InnerHandshakeResponse {
601 | const message = { ...baseInnerHandshakeResponse } as InnerHandshakeResponse;
602 | if (object.Code !== undefined && object.Code !== null) {
603 | message.Code = object.Code;
604 | } else {
605 | message.Code = 0;
606 | }
607 | if (object.Error !== undefined && object.Error !== null) {
608 | message.Error = object.Error;
609 | } else {
610 | message.Error = "";
611 | }
612 | return message;
613 | },
614 | };
615 |
616 | type Builtin =
617 | | Date
618 | | Function
619 | | Uint8Array
620 | | string
621 | | number
622 | | boolean
623 | | undefined
624 | | Long;
625 | export type DeepPartial = T extends Builtin
626 | ? T
627 | : T extends Array
628 | ? Array>
629 | : T extends ReadonlyArray
630 | ? ReadonlyArray>
631 | : T extends {}
632 | ? { [K in keyof T]?: DeepPartial }
633 | : Partial;
634 |
635 | if (_m0.util.Long !== Long) {
636 | _m0.util.Long = Long as any;
637 | _m0.configure();
638 | }
639 |
--------------------------------------------------------------------------------
/sdk/sdk.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/sdk/proto/common.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __assign = (this && this.__assign) || function () {
3 | __assign = Object.assign || function(t) {
4 | for (var s, i = 1, n = arguments.length; i < n; i++) {
5 | s = arguments[i];
6 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 | t[p] = s[p];
8 | }
9 | return t;
10 | };
11 | return __assign.apply(this, arguments);
12 | };
13 | var __importDefault = (this && this.__importDefault) || function (mod) {
14 | return (mod && mod.__esModule) ? mod : { "default": mod };
15 | };
16 | Object.defineProperty(exports, "__esModule", { value: true });
17 | exports.InnerHandshakeResponse = exports.InnerHandshakeReq = exports.Header = exports.Meta = exports.flagToJSON = exports.flagFromJSON = exports.Flag = exports.contentTypeToJSON = exports.contentTypeFromJSON = exports.ContentType = exports.metaTypeToJSON = exports.metaTypeFromJSON = exports.MetaType = exports.statusToJSON = exports.statusFromJSON = exports.Status = exports.protobufPackage = void 0;
18 | /* eslint-disable */
19 | var long_1 = __importDefault(require("long"));
20 | var minimal_1 = __importDefault(require("protobufjs/minimal"));
21 | exports.protobufPackage = "pkt";
22 | /** status is a uint16 value */
23 | var Status;
24 | (function (Status) {
25 | /** Success - client defined */
26 | Status[Status["Success"] = 0] = "Success";
27 | /** NoDestination - client error 100-200 */
28 | Status[Status["NoDestination"] = 100] = "NoDestination";
29 | Status[Status["InvalidPacketBody"] = 101] = "InvalidPacketBody";
30 | Status[Status["InvalidCommand"] = 103] = "InvalidCommand";
31 | Status[Status["Unauthorized"] = 105] = "Unauthorized";
32 | /** SystemException - server error 300-400 */
33 | Status[Status["SystemException"] = 300] = "SystemException";
34 | Status[Status["NotImplemented"] = 301] = "NotImplemented";
35 | /** SessionNotFound - specific error */
36 | Status[Status["SessionNotFound"] = 404] = "SessionNotFound";
37 | Status[Status["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
38 | })(Status = exports.Status || (exports.Status = {}));
39 | function statusFromJSON(object) {
40 | switch (object) {
41 | case 0:
42 | case "Success":
43 | return Status.Success;
44 | case 100:
45 | case "NoDestination":
46 | return Status.NoDestination;
47 | case 101:
48 | case "InvalidPacketBody":
49 | return Status.InvalidPacketBody;
50 | case 103:
51 | case "InvalidCommand":
52 | return Status.InvalidCommand;
53 | case 105:
54 | case "Unauthorized":
55 | return Status.Unauthorized;
56 | case 300:
57 | case "SystemException":
58 | return Status.SystemException;
59 | case 301:
60 | case "NotImplemented":
61 | return Status.NotImplemented;
62 | case 404:
63 | case "SessionNotFound":
64 | return Status.SessionNotFound;
65 | case -1:
66 | case "UNRECOGNIZED":
67 | default:
68 | return Status.UNRECOGNIZED;
69 | }
70 | }
71 | exports.statusFromJSON = statusFromJSON;
72 | function statusToJSON(object) {
73 | switch (object) {
74 | case Status.Success:
75 | return "Success";
76 | case Status.NoDestination:
77 | return "NoDestination";
78 | case Status.InvalidPacketBody:
79 | return "InvalidPacketBody";
80 | case Status.InvalidCommand:
81 | return "InvalidCommand";
82 | case Status.Unauthorized:
83 | return "Unauthorized";
84 | case Status.SystemException:
85 | return "SystemException";
86 | case Status.NotImplemented:
87 | return "NotImplemented";
88 | case Status.SessionNotFound:
89 | return "SessionNotFound";
90 | default:
91 | return "UNKNOWN";
92 | }
93 | }
94 | exports.statusToJSON = statusToJSON;
95 | var MetaType;
96 | (function (MetaType) {
97 | MetaType[MetaType["int"] = 0] = "int";
98 | MetaType[MetaType["string"] = 1] = "string";
99 | MetaType[MetaType["float"] = 2] = "float";
100 | MetaType[MetaType["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
101 | })(MetaType = exports.MetaType || (exports.MetaType = {}));
102 | function metaTypeFromJSON(object) {
103 | switch (object) {
104 | case 0:
105 | case "int":
106 | return MetaType.int;
107 | case 1:
108 | case "string":
109 | return MetaType.string;
110 | case 2:
111 | case "float":
112 | return MetaType.float;
113 | case -1:
114 | case "UNRECOGNIZED":
115 | default:
116 | return MetaType.UNRECOGNIZED;
117 | }
118 | }
119 | exports.metaTypeFromJSON = metaTypeFromJSON;
120 | function metaTypeToJSON(object) {
121 | switch (object) {
122 | case MetaType.int:
123 | return "int";
124 | case MetaType.string:
125 | return "string";
126 | case MetaType.float:
127 | return "float";
128 | default:
129 | return "UNKNOWN";
130 | }
131 | }
132 | exports.metaTypeToJSON = metaTypeToJSON;
133 | var ContentType;
134 | (function (ContentType) {
135 | ContentType[ContentType["Protobuf"] = 0] = "Protobuf";
136 | ContentType[ContentType["Json"] = 1] = "Json";
137 | ContentType[ContentType["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
138 | })(ContentType = exports.ContentType || (exports.ContentType = {}));
139 | function contentTypeFromJSON(object) {
140 | switch (object) {
141 | case 0:
142 | case "Protobuf":
143 | return ContentType.Protobuf;
144 | case 1:
145 | case "Json":
146 | return ContentType.Json;
147 | case -1:
148 | case "UNRECOGNIZED":
149 | default:
150 | return ContentType.UNRECOGNIZED;
151 | }
152 | }
153 | exports.contentTypeFromJSON = contentTypeFromJSON;
154 | function contentTypeToJSON(object) {
155 | switch (object) {
156 | case ContentType.Protobuf:
157 | return "Protobuf";
158 | case ContentType.Json:
159 | return "Json";
160 | default:
161 | return "UNKNOWN";
162 | }
163 | }
164 | exports.contentTypeToJSON = contentTypeToJSON;
165 | var Flag;
166 | (function (Flag) {
167 | Flag[Flag["Request"] = 0] = "Request";
168 | Flag[Flag["Response"] = 1] = "Response";
169 | Flag[Flag["Push"] = 2] = "Push";
170 | Flag[Flag["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
171 | })(Flag = exports.Flag || (exports.Flag = {}));
172 | function flagFromJSON(object) {
173 | switch (object) {
174 | case 0:
175 | case "Request":
176 | return Flag.Request;
177 | case 1:
178 | case "Response":
179 | return Flag.Response;
180 | case 2:
181 | case "Push":
182 | return Flag.Push;
183 | case -1:
184 | case "UNRECOGNIZED":
185 | default:
186 | return Flag.UNRECOGNIZED;
187 | }
188 | }
189 | exports.flagFromJSON = flagFromJSON;
190 | function flagToJSON(object) {
191 | switch (object) {
192 | case Flag.Request:
193 | return "Request";
194 | case Flag.Response:
195 | return "Response";
196 | case Flag.Push:
197 | return "Push";
198 | default:
199 | return "UNKNOWN";
200 | }
201 | }
202 | exports.flagToJSON = flagToJSON;
203 | var baseMeta = { key: "", value: "", type: 0 };
204 | exports.Meta = {
205 | encode: function (message, writer) {
206 | if (writer === void 0) { writer = minimal_1.default.Writer.create(); }
207 | if (message.key !== "") {
208 | writer.uint32(10).string(message.key);
209 | }
210 | if (message.value !== "") {
211 | writer.uint32(18).string(message.value);
212 | }
213 | if (message.type !== 0) {
214 | writer.uint32(24).int32(message.type);
215 | }
216 | return writer;
217 | },
218 | decode: function (input, length) {
219 | var reader = input instanceof minimal_1.default.Reader ? input : new minimal_1.default.Reader(input);
220 | var end = length === undefined ? reader.len : reader.pos + length;
221 | var message = __assign({}, baseMeta);
222 | while (reader.pos < end) {
223 | var tag = reader.uint32();
224 | switch (tag >>> 3) {
225 | case 1:
226 | message.key = reader.string();
227 | break;
228 | case 2:
229 | message.value = reader.string();
230 | break;
231 | case 3:
232 | message.type = reader.int32();
233 | break;
234 | default:
235 | reader.skipType(tag & 7);
236 | break;
237 | }
238 | }
239 | return message;
240 | },
241 | fromJSON: function (object) {
242 | var message = __assign({}, baseMeta);
243 | if (object.key !== undefined && object.key !== null) {
244 | message.key = String(object.key);
245 | }
246 | else {
247 | message.key = "";
248 | }
249 | if (object.value !== undefined && object.value !== null) {
250 | message.value = String(object.value);
251 | }
252 | else {
253 | message.value = "";
254 | }
255 | if (object.type !== undefined && object.type !== null) {
256 | message.type = metaTypeFromJSON(object.type);
257 | }
258 | else {
259 | message.type = 0;
260 | }
261 | return message;
262 | },
263 | toJSON: function (message) {
264 | var obj = {};
265 | message.key !== undefined && (obj.key = message.key);
266 | message.value !== undefined && (obj.value = message.value);
267 | message.type !== undefined && (obj.type = metaTypeToJSON(message.type));
268 | return obj;
269 | },
270 | fromPartial: function (object) {
271 | var message = __assign({}, baseMeta);
272 | if (object.key !== undefined && object.key !== null) {
273 | message.key = object.key;
274 | }
275 | else {
276 | message.key = "";
277 | }
278 | if (object.value !== undefined && object.value !== null) {
279 | message.value = object.value;
280 | }
281 | else {
282 | message.value = "";
283 | }
284 | if (object.type !== undefined && object.type !== null) {
285 | message.type = object.type;
286 | }
287 | else {
288 | message.type = 0;
289 | }
290 | return message;
291 | },
292 | };
293 | var baseHeader = {
294 | command: "",
295 | channelId: "",
296 | sequence: 0,
297 | flag: 0,
298 | status: 0,
299 | dest: "",
300 | };
301 | exports.Header = {
302 | encode: function (message, writer) {
303 | if (writer === void 0) { writer = minimal_1.default.Writer.create(); }
304 | if (message.command !== "") {
305 | writer.uint32(10).string(message.command);
306 | }
307 | if (message.channelId !== "") {
308 | writer.uint32(18).string(message.channelId);
309 | }
310 | if (message.sequence !== 0) {
311 | writer.uint32(24).uint32(message.sequence);
312 | }
313 | if (message.flag !== 0) {
314 | writer.uint32(32).int32(message.flag);
315 | }
316 | if (message.status !== 0) {
317 | writer.uint32(40).int32(message.status);
318 | }
319 | if (message.dest !== "") {
320 | writer.uint32(50).string(message.dest);
321 | }
322 | for (var _i = 0, _a = message.meta; _i < _a.length; _i++) {
323 | var v = _a[_i];
324 | exports.Meta.encode(v, writer.uint32(58).fork()).ldelim();
325 | }
326 | return writer;
327 | },
328 | decode: function (input, length) {
329 | var reader = input instanceof minimal_1.default.Reader ? input : new minimal_1.default.Reader(input);
330 | var end = length === undefined ? reader.len : reader.pos + length;
331 | var message = __assign({}, baseHeader);
332 | message.meta = [];
333 | while (reader.pos < end) {
334 | var tag = reader.uint32();
335 | switch (tag >>> 3) {
336 | case 1:
337 | message.command = reader.string();
338 | break;
339 | case 2:
340 | message.channelId = reader.string();
341 | break;
342 | case 3:
343 | message.sequence = reader.uint32();
344 | break;
345 | case 4:
346 | message.flag = reader.int32();
347 | break;
348 | case 5:
349 | message.status = reader.int32();
350 | break;
351 | case 6:
352 | message.dest = reader.string();
353 | break;
354 | case 7:
355 | message.meta.push(exports.Meta.decode(reader, reader.uint32()));
356 | break;
357 | default:
358 | reader.skipType(tag & 7);
359 | break;
360 | }
361 | }
362 | return message;
363 | },
364 | fromJSON: function (object) {
365 | var message = __assign({}, baseHeader);
366 | message.meta = [];
367 | if (object.command !== undefined && object.command !== null) {
368 | message.command = String(object.command);
369 | }
370 | else {
371 | message.command = "";
372 | }
373 | if (object.channelId !== undefined && object.channelId !== null) {
374 | message.channelId = String(object.channelId);
375 | }
376 | else {
377 | message.channelId = "";
378 | }
379 | if (object.sequence !== undefined && object.sequence !== null) {
380 | message.sequence = Number(object.sequence);
381 | }
382 | else {
383 | message.sequence = 0;
384 | }
385 | if (object.flag !== undefined && object.flag !== null) {
386 | message.flag = flagFromJSON(object.flag);
387 | }
388 | else {
389 | message.flag = 0;
390 | }
391 | if (object.status !== undefined && object.status !== null) {
392 | message.status = statusFromJSON(object.status);
393 | }
394 | else {
395 | message.status = 0;
396 | }
397 | if (object.dest !== undefined && object.dest !== null) {
398 | message.dest = String(object.dest);
399 | }
400 | else {
401 | message.dest = "";
402 | }
403 | if (object.meta !== undefined && object.meta !== null) {
404 | for (var _i = 0, _a = object.meta; _i < _a.length; _i++) {
405 | var e = _a[_i];
406 | message.meta.push(exports.Meta.fromJSON(e));
407 | }
408 | }
409 | return message;
410 | },
411 | toJSON: function (message) {
412 | var obj = {};
413 | message.command !== undefined && (obj.command = message.command);
414 | message.channelId !== undefined && (obj.channelId = message.channelId);
415 | message.sequence !== undefined && (obj.sequence = message.sequence);
416 | message.flag !== undefined && (obj.flag = flagToJSON(message.flag));
417 | message.status !== undefined && (obj.status = statusToJSON(message.status));
418 | message.dest !== undefined && (obj.dest = message.dest);
419 | if (message.meta) {
420 | obj.meta = message.meta.map(function (e) { return (e ? exports.Meta.toJSON(e) : undefined); });
421 | }
422 | else {
423 | obj.meta = [];
424 | }
425 | return obj;
426 | },
427 | fromPartial: function (object) {
428 | var message = __assign({}, baseHeader);
429 | message.meta = [];
430 | if (object.command !== undefined && object.command !== null) {
431 | message.command = object.command;
432 | }
433 | else {
434 | message.command = "";
435 | }
436 | if (object.channelId !== undefined && object.channelId !== null) {
437 | message.channelId = object.channelId;
438 | }
439 | else {
440 | message.channelId = "";
441 | }
442 | if (object.sequence !== undefined && object.sequence !== null) {
443 | message.sequence = object.sequence;
444 | }
445 | else {
446 | message.sequence = 0;
447 | }
448 | if (object.flag !== undefined && object.flag !== null) {
449 | message.flag = object.flag;
450 | }
451 | else {
452 | message.flag = 0;
453 | }
454 | if (object.status !== undefined && object.status !== null) {
455 | message.status = object.status;
456 | }
457 | else {
458 | message.status = 0;
459 | }
460 | if (object.dest !== undefined && object.dest !== null) {
461 | message.dest = object.dest;
462 | }
463 | else {
464 | message.dest = "";
465 | }
466 | if (object.meta !== undefined && object.meta !== null) {
467 | for (var _i = 0, _a = object.meta; _i < _a.length; _i++) {
468 | var e = _a[_i];
469 | message.meta.push(exports.Meta.fromPartial(e));
470 | }
471 | }
472 | return message;
473 | },
474 | };
475 | var baseInnerHandshakeReq = { ServiceId: "" };
476 | exports.InnerHandshakeReq = {
477 | encode: function (message, writer) {
478 | if (writer === void 0) { writer = minimal_1.default.Writer.create(); }
479 | if (message.ServiceId !== "") {
480 | writer.uint32(10).string(message.ServiceId);
481 | }
482 | return writer;
483 | },
484 | decode: function (input, length) {
485 | var reader = input instanceof minimal_1.default.Reader ? input : new minimal_1.default.Reader(input);
486 | var end = length === undefined ? reader.len : reader.pos + length;
487 | var message = __assign({}, baseInnerHandshakeReq);
488 | while (reader.pos < end) {
489 | var tag = reader.uint32();
490 | switch (tag >>> 3) {
491 | case 1:
492 | message.ServiceId = reader.string();
493 | break;
494 | default:
495 | reader.skipType(tag & 7);
496 | break;
497 | }
498 | }
499 | return message;
500 | },
501 | fromJSON: function (object) {
502 | var message = __assign({}, baseInnerHandshakeReq);
503 | if (object.ServiceId !== undefined && object.ServiceId !== null) {
504 | message.ServiceId = String(object.ServiceId);
505 | }
506 | else {
507 | message.ServiceId = "";
508 | }
509 | return message;
510 | },
511 | toJSON: function (message) {
512 | var obj = {};
513 | message.ServiceId !== undefined && (obj.ServiceId = message.ServiceId);
514 | return obj;
515 | },
516 | fromPartial: function (object) {
517 | var message = __assign({}, baseInnerHandshakeReq);
518 | if (object.ServiceId !== undefined && object.ServiceId !== null) {
519 | message.ServiceId = object.ServiceId;
520 | }
521 | else {
522 | message.ServiceId = "";
523 | }
524 | return message;
525 | },
526 | };
527 | var baseInnerHandshakeResponse = { Code: 0, Error: "" };
528 | exports.InnerHandshakeResponse = {
529 | encode: function (message, writer) {
530 | if (writer === void 0) { writer = minimal_1.default.Writer.create(); }
531 | if (message.Code !== 0) {
532 | writer.uint32(8).uint32(message.Code);
533 | }
534 | if (message.Error !== "") {
535 | writer.uint32(18).string(message.Error);
536 | }
537 | return writer;
538 | },
539 | decode: function (input, length) {
540 | var reader = input instanceof minimal_1.default.Reader ? input : new minimal_1.default.Reader(input);
541 | var end = length === undefined ? reader.len : reader.pos + length;
542 | var message = __assign({}, baseInnerHandshakeResponse);
543 | while (reader.pos < end) {
544 | var tag = reader.uint32();
545 | switch (tag >>> 3) {
546 | case 1:
547 | message.Code = reader.uint32();
548 | break;
549 | case 2:
550 | message.Error = reader.string();
551 | break;
552 | default:
553 | reader.skipType(tag & 7);
554 | break;
555 | }
556 | }
557 | return message;
558 | },
559 | fromJSON: function (object) {
560 | var message = __assign({}, baseInnerHandshakeResponse);
561 | if (object.Code !== undefined && object.Code !== null) {
562 | message.Code = Number(object.Code);
563 | }
564 | else {
565 | message.Code = 0;
566 | }
567 | if (object.Error !== undefined && object.Error !== null) {
568 | message.Error = String(object.Error);
569 | }
570 | else {
571 | message.Error = "";
572 | }
573 | return message;
574 | },
575 | toJSON: function (message) {
576 | var obj = {};
577 | message.Code !== undefined && (obj.Code = message.Code);
578 | message.Error !== undefined && (obj.Error = message.Error);
579 | return obj;
580 | },
581 | fromPartial: function (object) {
582 | var message = __assign({}, baseInnerHandshakeResponse);
583 | if (object.Code !== undefined && object.Code !== null) {
584 | message.Code = object.Code;
585 | }
586 | else {
587 | message.Code = 0;
588 | }
589 | if (object.Error !== undefined && object.Error !== null) {
590 | message.Error = object.Error;
591 | }
592 | else {
593 | message.Error = "";
594 | }
595 | return message;
596 | },
597 | };
598 | if (minimal_1.default.util.Long !== long_1.default) {
599 | minimal_1.default.util.Long = long_1.default;
600 | minimal_1.default.configure();
601 | }
602 | //# sourceMappingURL=common.js.map
--------------------------------------------------------------------------------
/src/sdk.ts:
--------------------------------------------------------------------------------
1 | import { w3cwebsocket, IMessageEvent, ICloseEvent } from 'websocket';
2 | import { Buffer } from 'buffer';
3 | import log from 'loglevel-es';
4 | import { Command, LogicPkt, MagicBasicPktInt, MessageType, Ping } from './packet';
5 | import { Flag, Status } from './proto/common';
6 | import { LoginReq, LoginResp, MessageReq, MessageResp, MessagePush, GroupCreateResp, GroupGetResp, MessageIndexResp, MessageContentResp, ErrorResp, KickoutNotify, MessageAckReq, MessageIndexReq, MessageIndex, MessageContentReq, MessageContent, GroupCreateReq, GroupJoinReq, GroupQuitReq, GroupGetReq } from './proto/protocol';
7 | import { doLogin, LoginBody } from './login';
8 | import Long from 'long';
9 | import localforage from 'localforage';
10 |
11 | const heartbeatInterval = 55 * 1000 // seconds
12 | const sendTimeout = 5 * 1000 // 10 seconds
13 |
14 | enum TimeUnit {
15 | Second = 1000,
16 | Millisecond = 1,
17 | }
18 |
19 | export let sleep = async (second: number, Unit: TimeUnit = TimeUnit.Second): Promise => {
20 | return new Promise((resolve, _) => {
21 | setTimeout(() => {
22 | resolve()
23 | }, second * Unit)
24 | })
25 | }
26 |
27 | export enum State {
28 | INIT,
29 | CONNECTING,
30 | CONNECTED,
31 | RECONNECTING,
32 | CLOSEING,
33 | CLOSED,
34 | }
35 |
36 | // 客户端自定义的状态码范围 [10, 100)
37 | export enum KIMStatus {
38 | RequestTimeout = 10,
39 | SendFailed = 11,
40 | }
41 |
42 | export enum KIMEvent {
43 | Reconnecting = "Reconnecting", //重连中
44 | Reconnected = "Reconnected", //重连成功
45 | Closed = "Closed",
46 | Kickout = "Kickout", // 被踢
47 | }
48 |
49 | export class Response {
50 | status: number
51 | dest?: string
52 | payload: Uint8Array
53 | constructor(status: number, dest?: string, payload: Uint8Array = new Uint8Array()) {
54 | this.status = status;
55 | this.dest = dest;
56 | this.payload = payload;
57 | }
58 | }
59 |
60 | export class Request {
61 | sendTime: number
62 | data: LogicPkt
63 | callback: (response: LogicPkt) => void
64 | constructor(data: LogicPkt, callback: (response: LogicPkt) => void) {
65 | this.sendTime = Date.now()
66 | this.data = data
67 | this.callback = callback
68 | }
69 | }
70 |
71 | const pageCount = 50
72 |
73 | export class OfflineMessages {
74 | private cli: KIMClient
75 | private groupmessages = new Map()
76 | private usermessages = new Map()
77 | constructor(cli: KIMClient, indexes: MessageIndex[]) {
78 | this.cli = cli
79 | // 通常离线消息的读取是从下向上,因此这里提前倒序下
80 | for (let index = indexes.length - 1; index >= 0; index--) {
81 | const idx = indexes[index];
82 | let message = new Message(idx.messageId, idx.sendTime)
83 | if (idx.direction == 1) {
84 | message.sender = cli.account
85 | message.receiver = idx.accountB
86 | } else {
87 | message.sender = idx.accountB
88 | message.receiver = cli.account
89 | }
90 |
91 | if (!!idx.group) {
92 | if (!this.groupmessages.has(idx.group)) {
93 | this.groupmessages.set(idx.group, new Array())
94 | }
95 | this.groupmessages.get(idx.group)?.push(message)
96 | } else {
97 | if (!this.usermessages.has(idx.accountB)) {
98 | this.usermessages.set(idx.accountB, new Array())
99 | }
100 | this.usermessages.get(idx.accountB)?.push(message)
101 | }
102 | }
103 | }
104 | /**
105 | * 获取离线消息群列表
106 | */
107 | listGroups(): Array {
108 | let arr = new Array()
109 | this.groupmessages.forEach((_, key) => {
110 | arr.push(key)
111 | })
112 | return arr
113 | }
114 | /**
115 | * 获取离线消息用户列表
116 | */
117 | listUsers(): Array {
118 | let arr = new Array()
119 | this.usermessages.forEach((_, key) => {
120 | arr.push(key)
121 | })
122 | return arr
123 | }
124 | /**
125 | * lazy load group offline messages, the page count is 50
126 | * @param page page number, start from one
127 | */
128 | async loadGroup(group: string, page: number): Promise {
129 | let messages = this.groupmessages.get(group)
130 | if (!messages) {
131 | return new Array();
132 | }
133 | let msgs = await this.lazyLoad(messages, page);
134 | return msgs
135 | }
136 | async loadUser(account: string, page: number): Promise {
137 | let messages = this.usermessages.get(account)
138 | if (!messages) {
139 | return new Array();
140 | }
141 | let msgs = await this.lazyLoad(messages, page);
142 | return msgs
143 | }
144 | /**
145 | * 获取指定群的离线消息数据
146 | * @param group 群ID
147 | */
148 | getGroupMessagesCount(group: string): number {
149 | let messages = this.groupmessages.get(group)
150 | if (!messages) {
151 | return 0
152 | }
153 | return messages.length
154 | }
155 | /**
156 | * 获取指定用户的离线消息数量
157 | * @param account 用户
158 | */
159 | getUserMessagesCount(account: string): number {
160 | let messages = this.usermessages.get(account)
161 | if (!messages) {
162 | return 0
163 | }
164 | return messages.length
165 | }
166 | private async lazyLoad(messages: Array, page: number): Promise> {
167 | let i = (page - 1) * pageCount
168 | let msgs = messages.slice(i, i + pageCount)
169 | log.debug(msgs)
170 | if (!msgs || msgs.length == 0) {
171 | return new Array();
172 | }
173 | if (!!msgs[0].body) {
174 | return msgs
175 | }
176 | //load from server
177 | let { status, contents } = await this.loadcontent(msgs.map(idx => idx.messageId))
178 | if (status != Status.Success) {
179 | return msgs
180 | }
181 | log.debug(`load content ${contents.map(c => c.body)}`)
182 | if (contents.length == msgs.length) {
183 | for (let index = 0; index < msgs.length; index++) {
184 | let msg = msgs[index];
185 | let original = messages[i + index]
186 | let content = contents[index]
187 | Object.assign(msg, content)
188 | Object.assign(original, content)
189 | }
190 | }
191 | return msgs
192 | }
193 | private async loadcontent(messageIds: Long[]): Promise<{ status: number, contents: MessageContent[] }> {
194 | let req = MessageContentReq.encode({ messageIds })
195 | let pkt = LogicPkt.build(Command.OfflineContent, "", req.finish())
196 | let resp = await this.cli.request(pkt)
197 | if (resp.status != Status.Success) {
198 | let err = ErrorResp.decode(pkt.payload)
199 | log.error(err)
200 | return { status: resp.status, contents: new Array() }
201 | }
202 | log.info(resp)
203 | let respbody = MessageContentResp.decode(resp.payload)
204 | return { status: resp.status, contents: respbody.contents }
205 | }
206 | }
207 |
208 | export class Message {
209 | messageId: Long;
210 | type?: number;
211 | body?: string;
212 | extra?: string;
213 | sender?: string;
214 | receiver?: string;
215 | group?: string;
216 | sendTime: Long;
217 | arrivalTime: number;
218 | constructor(messageId: Long, sendTime: Long) {
219 | this.messageId = messageId
220 | this.sendTime = sendTime
221 | this.arrivalTime = Date.now()
222 | }
223 | }
224 |
225 | export class Content {
226 | type?: number;
227 | body: string;
228 | extra?: string;
229 | constructor(body: string, type: number = MessageType.Text, extra?: string) {
230 | this.type = type
231 | this.body = body
232 | this.extra = extra
233 | }
234 | }
235 |
236 | export class KIMClient {
237 | wsurl: string
238 | private req: LoginBody
239 | state = State.INIT
240 | channelId: string
241 | account: string
242 | private conn?: w3cwebsocket
243 | private lastRead: number
244 | private lastMessage?: Message
245 | private unack: number = 0
246 | private listeners = new Map void>()
247 | private messageCallback: (m: Message) => void
248 | private offmessageCallback: (m: OfflineMessages) => void
249 | private closeCallback?: () => void
250 | // 全双工请求队列
251 | private sendq = new Map()
252 | constructor(url: string, req: LoginBody) {
253 | this.wsurl = url
254 | this.req = req
255 | this.lastRead = Date.now()
256 | this.channelId = ""
257 | this.account = ""
258 | this.messageCallback = (m: Message) => {
259 | log.warn(`throw a message from ${m.sender} -- ${m.body}\nPlease check you had register a onmessage callback method before login`)
260 | }
261 | this.offmessageCallback = (m: OfflineMessages) => {
262 | log.warn(`throw OfflineMessages.\nPlease check you had register a onofflinemessage callback method before login`)
263 | }
264 | }
265 | register(events: string[], callback: (e: KIMEvent) => void) {
266 | // 注册事件到Client中。
267 | events.forEach((event) => {
268 | this.listeners.set(event, callback)
269 | })
270 | }
271 | onmessage(cb: (m: Message) => void) {
272 | this.messageCallback = cb
273 | }
274 | onofflinemessage(cb: (m: OfflineMessages) => void) {
275 | this.offmessageCallback = cb
276 | }
277 | // 1、登录
278 | async login(): Promise<{ success: boolean, err?: Error }> {
279 | if (this.state == State.CONNECTED) {
280 | return { success: false, err: new Error("client has already been connected") }
281 | }
282 | this.state = State.CONNECTING
283 | let { success, err, channelId, account, conn } = await doLogin(this.wsurl, this.req)
284 | if (!success) {
285 | this.state = State.INIT
286 | return { success, err }
287 | }
288 | log.info("login - ", success)
289 | // overwrite onmessage
290 | conn.onmessage = (evt: IMessageEvent) => {
291 | try {
292 | // 重置lastRead
293 | this.lastRead = Date.now()
294 | let buf = Buffer.from(evt.data)
295 | let magic = buf.readInt32BE()
296 | if (magic == MagicBasicPktInt) {//目前只有心跳包pong
297 | log.debug(`recv a basic packet - ${buf.join(",")}`)
298 | return
299 | }
300 | let pkt = LogicPkt.from(buf)
301 | this.packetHandler(pkt)
302 | } catch (error) {
303 | log.error(evt.data, error)
304 | }
305 | }
306 | conn.onerror = (error) => {
307 | log.info("websocket error: ", error)
308 | this.errorHandler(error)
309 | }
310 | conn.onclose = (e: ICloseEvent) => {
311 | log.debug("event[onclose] fired")
312 | if (this.state == State.CLOSEING) {
313 | this.onclose("logout")
314 | return
315 | }
316 | this.errorHandler(new Error(e.reason))
317 | }
318 | this.conn = conn
319 | this.channelId = channelId || ""
320 | this.account = account || ""
321 | await this.loadOfflineMessage()
322 | // success
323 | this.state = State.CONNECTED
324 | this.heartbeatLoop()
325 | this.readDeadlineLoop()
326 | this.messageAckLoop()
327 | return { success, err }
328 | }
329 | logout(): Promise {
330 | return new Promise((resolve, _) => {
331 | if (this.state === State.CLOSEING) {
332 | return
333 | }
334 | this.state = State.CLOSEING
335 | if (!this.conn) {
336 | return
337 | }
338 | let tr = setTimeout(() => {
339 | log.debug("oh no,logout is timeout~")
340 | this.onclose("logout")
341 | resolve()
342 | }, 1500)
343 |
344 | this.closeCallback = async () => {
345 | clearTimeout(tr)
346 | await sleep(1)
347 | resolve()
348 | }
349 |
350 | this.conn.close()
351 | log.info("Connection closing...")
352 | })
353 | }
354 | /**
355 | * 给用户dest发送一条消息
356 | * @param dest 用户账号
357 | * @param req 请求的消息内容
358 | * @returns status KIMStatus|Status
359 | */
360 | async talkToUser(dest: string, req: Content, retry: number = 3): Promise<{ status: number, resp?: MessageResp, err?: ErrorResp }> {
361 | return this.talk(Command.ChatUserTalk, dest, MessageReq.fromJSON(req), retry)
362 | }
363 | /**
364 | * 给群dest发送一条消息
365 | * @param dest 群ID
366 | * @param req 请求的消息内容
367 | * @returns status KIMStatus|Status
368 | */
369 | async talkToGroup(dest: string, req: Content, retry: number = 3): Promise<{ status: number, resp?: MessageResp, err?: ErrorResp }> {
370 | return this.talk(Command.ChatGroupTalk, dest, MessageReq.fromJSON(req), retry)
371 | }
372 | async createGroup(req: {
373 | name: string;
374 | avatar?: string;
375 | introduction?: string;
376 | members: string[];
377 | }): Promise<{ status: number, resp?: GroupCreateResp, err?: ErrorResp }> {
378 | let req2 = GroupCreateReq.fromJSON(req)
379 | req2.owner = this.account
380 | if (!req2.members.find(v => v == this.account)) {
381 | req2.members.push(this.account)
382 | }
383 | let pbreq = GroupCreateReq.encode(req2).finish()
384 | let pkt = LogicPkt.build(Command.GroupCreate, "", pbreq)
385 | let resp = await this.request(pkt)
386 | if (resp.status != Status.Success) {
387 | let err = ErrorResp.decode(resp.payload)
388 | return { status: resp.status, err: err }
389 | }
390 | return { status: Status.Success, resp: GroupCreateResp.decode(resp.payload) }
391 | }
392 | async joinGroup(req: GroupJoinReq): Promise<{ status: number, err?: ErrorResp }> {
393 | let pbreq = GroupJoinReq.encode(req).finish()
394 | let pkt = LogicPkt.build(Command.GroupJoin, "", pbreq)
395 | let resp = await this.request(pkt)
396 | if (resp.status != Status.Success) {
397 | let err = ErrorResp.decode(resp.payload)
398 | return { status: resp.status, err: err }
399 | }
400 | return { status: Status.Success }
401 | }
402 | async quitGroup(req: GroupQuitReq): Promise<{ status: number, err?: ErrorResp }> {
403 | let pbreq = GroupQuitReq.encode(req).finish()
404 | let pkt = LogicPkt.build(Command.GroupQuit, "", pbreq)
405 | let resp = await this.request(pkt)
406 | if (resp.status != Status.Success) {
407 | let err = ErrorResp.decode(resp.payload)
408 | return { status: resp.status, err: err }
409 | }
410 | return { status: Status.Success }
411 | }
412 | async GetGroup(req: GroupGetReq): Promise<{ status: number, resp?: GroupGetResp, err?: ErrorResp }> {
413 | let pbreq = GroupGetReq.encode(req).finish()
414 | let pkt = LogicPkt.build(Command.GroupDetail, "", pbreq)
415 | let resp = await this.request(pkt)
416 | if (resp.status != Status.Success) {
417 | let err = ErrorResp.decode(resp.payload)
418 | return { status: resp.status, err: err }
419 | }
420 | return { status: Status.Success, resp: GroupGetResp.decode(resp.payload) }
421 | }
422 | private async talk(command: string, dest: string, req: MessageReq, retry: number): Promise<{ status: number, resp?: MessageResp, err?: ErrorResp }> {
423 | let pbreq = MessageReq.encode(req).finish()
424 | for (let index = 0; index < retry + 1; index++) {
425 | let pkt = LogicPkt.build(command, dest, pbreq)
426 | let resp = await this.request(pkt)
427 | if (resp.status == Status.Success) {
428 | return { status: Status.Success, resp: MessageResp.decode(resp.payload) }
429 | }
430 | if (resp.status >= 300 && resp.status < 400) {
431 | // 消息重发
432 | log.warn("retry to send message")
433 | await sleep(2)
434 | continue
435 | }
436 | let err = ErrorResp.decode(resp.payload)
437 | return { status: resp.status, err: err }
438 | }
439 | return { status: KIMStatus.SendFailed, err: new Error("over max retry times") }
440 | }
441 | async request(data: LogicPkt): Promise {
442 | return new Promise((resolve, _) => {
443 | let seq = data.sequence
444 |
445 | let tr = setTimeout(() => {
446 | // remove from sendq
447 | this.sendq.delete(seq)
448 | resolve(new Response(KIMStatus.RequestTimeout))
449 | }, sendTimeout)
450 |
451 | // asynchronous wait ack from server
452 | let callback = (pkt: LogicPkt) => {
453 | clearTimeout(tr)
454 | // remove from sendq
455 | this.sendq.delete(seq)
456 | resolve(new Response(pkt.status, pkt.dest, pkt.payload))
457 | }
458 | log.debug(`request seq:${seq} command:${data.command}`)
459 |
460 | this.sendq.set(seq, new Request(data, callback))
461 | if (!this.send(data.bytes())) {
462 | resolve(new Response(KIMStatus.SendFailed))
463 | }
464 | })
465 | }
466 | private fireEvent(event: KIMEvent) {
467 | let listener = this.listeners.get(event)
468 | if (!!listener) {
469 | listener(event)
470 | }
471 | }
472 | private async packetHandler(pkt: LogicPkt) {
473 | log.debug("received packet: ", pkt)
474 | if (pkt.status >= 400) {
475 | log.info(`need relogin due to status ${pkt.status}`)
476 | this.conn?.close()
477 | return
478 | }
479 | if (pkt.flag == Flag.Response) {
480 | let req = this.sendq.get(pkt.sequence)
481 | if (req) {
482 | req.callback(pkt)
483 | } else {
484 | log.error(`req of ${pkt.sequence} no found in sendq`)
485 | }
486 | return
487 | }
488 | switch (pkt.command) {
489 | case Command.ChatUserTalk:
490 | case Command.ChatGroupTalk:
491 | let push = MessagePush.decode(pkt.payload)
492 | let message = new Message(push.messageId, push.sendTime)
493 | Object.assign(message, push)
494 | message.receiver = this.account
495 | if (pkt.command == Command.ChatGroupTalk) {
496 | message.group = pkt.dest
497 | }
498 | if (!await Store.exist(message.messageId)) {
499 | // 确保状态处于CONNECTED,才能执行消息ACK
500 | if (this.state == State.CONNECTED) {
501 | this.lastMessage = message
502 | this.unack++
503 | try {
504 | this.messageCallback(message)
505 | } catch (error) {
506 | log.error(error)
507 | }
508 | }
509 | // 消息保存到数据库中。
510 | await Store.insert(message)
511 | }
512 | break;
513 | case Command.SignIn:
514 | let ko = KickoutNotify.decode(pkt.payload)
515 | if (ko.channelId == this.channelId) {
516 | this.logout()
517 | this.fireEvent(KIMEvent.Kickout)
518 | }
519 | break;
520 | }
521 | }
522 | // 2、心跳
523 | private heartbeatLoop() {
524 | log.debug("heartbeatLoop start")
525 | let start = Date.now()
526 | let loop = () => {
527 | if (this.state != State.CONNECTED) {
528 | log.debug("heartbeatLoop exited")
529 | return
530 | }
531 | if (Date.now() - start >= heartbeatInterval) {
532 | log.debug(`>>> send ping ; state is ${this.state}`)
533 | start = Date.now()
534 | this.send(Ping)
535 | }
536 | setTimeout(loop, 500)
537 | }
538 | setTimeout(loop, 500)
539 | }
540 | // 3、读超时
541 | private readDeadlineLoop() {
542 | log.debug("deadlineLoop start")
543 | let loop = () => {
544 | if (this.state != State.CONNECTED) {
545 | log.debug("deadlineLoop exited")
546 | return
547 | }
548 | if ((Date.now() - this.lastRead) > 3 * heartbeatInterval) {
549 | // 如果超时就调用errorHandler处理
550 | this.errorHandler(new Error("read timeout"))
551 | }
552 | setTimeout(loop, 500)
553 | }
554 | setTimeout(loop, 500)
555 | }
556 | private messageAckLoop() {
557 | let start = Date.now()
558 | const delay = 500 //ms
559 | let loop = async () => {
560 | if (this.state != State.CONNECTED) {
561 | log.debug("messageAckLoop exited")
562 | return
563 | }
564 | let msg = this.lastMessage // lock this message
565 | if (!!msg && (Date.now() - start > 3000)) {
566 | let overflow = this.unack > 10
567 | this.unack = 0 // reset unack before ack
568 | this.lastMessage = undefined //reset last message
569 |
570 | let diff = Date.now() - msg.arrivalTime
571 | if (!overflow && diff < delay) {
572 | await sleep(delay - diff, TimeUnit.Millisecond)
573 | }
574 | let req = MessageAckReq.encode({ messageId: msg.messageId })
575 | let pkt = LogicPkt.build(Command.ChatTalkAck, "", req.finish())
576 | start = Date.now()
577 | this.send(pkt.bytes())
578 | // 修改本地存储中最后一条ACK消息记录
579 | await Store.setAck(msg.messageId)
580 | }
581 | setTimeout(loop, 500)
582 | }
583 | setTimeout(loop, 500)
584 | }
585 | private async loadOfflineMessage() {
586 | log.debug("loadOfflineMessage start")
587 | // 1. 加载消息索引
588 | let loadIndex = async (messageId: Long = Long.ZERO): Promise<{ status: number, indexes?: MessageIndex[] }> => {
589 | let req = MessageIndexReq.encode({ messageId })
590 | let pkt = LogicPkt.build(Command.OfflineIndex, "", req.finish())
591 | let resp = await this.request(pkt)
592 | if (resp.status != Status.Success) {
593 | let err = ErrorResp.decode(pkt.payload)
594 | log.error(err)
595 | return { status: resp.status }
596 | }
597 | let respbody = MessageIndexResp.decode(resp.payload)
598 | return { status: resp.status, indexes: respbody.indexes }
599 | }
600 | let offmessages = new Array();
601 | let messageId = await Store.lastId()
602 | while (true) {
603 | let { status, indexes } = await loadIndex(messageId)
604 | if (status != Status.Success) {
605 | break
606 | }
607 | if (!indexes || !indexes.length) {
608 | break
609 | }
610 | messageId = indexes[indexes.length - 1].messageId
611 | offmessages = offmessages.concat(indexes)
612 | }
613 | log.info(`load offline indexes - ${offmessages.map(msg => msg.messageId.toString())}`)
614 | let om = new OfflineMessages(this, offmessages)
615 | this.offmessageCallback(om)
616 | }
617 | // 表示连接中止
618 | private onclose(reason: string) {
619 | if (this.state == State.CLOSED) {
620 | return
621 | }
622 | this.state = State.CLOSED
623 |
624 | log.info("connection closed due to " + reason)
625 | this.conn = undefined
626 | this.channelId = ""
627 | this.account = ""
628 | // 通知上层应用
629 | this.fireEvent(KIMEvent.Closed)
630 | if (this.closeCallback) {
631 | this.closeCallback()
632 | }
633 | }
634 | // 4. 自动重连
635 | private async errorHandler(error: Error) {
636 | // 如果是主动断开连接,就没有必要自动重连
637 | // 比如收到被踢,或者主动调用logout()方法
638 | if (this.state == State.CLOSED || this.state == State.CLOSEING) {
639 | return
640 | }
641 | this.state = State.RECONNECTING
642 | this.fireEvent(KIMEvent.Reconnecting)
643 | // 重连10次
644 | for (let index = 0; index < 10; index++) {
645 | await sleep(3)
646 | try {
647 | log.info("try to relogin")
648 | let { success, err } = await this.login()
649 | if (success) {
650 | this.fireEvent(KIMEvent.Reconnected)
651 | return
652 | }
653 | log.info(err)
654 | } catch (error) {
655 | log.warn(error)
656 | }
657 | }
658 | this.onclose("reconnect timeout")
659 | }
660 | private send(data: Buffer | Uint8Array): boolean {
661 | try {
662 | if (this.conn == null) {
663 | return false
664 | }
665 | this.conn.send(data)
666 | } catch (error) {
667 | // handle write error
668 | this.errorHandler(new Error("write timeout"))
669 | return false
670 | }
671 | return true
672 | }
673 | }
674 |
675 | class MsgStorage {
676 | constructor() {
677 | localforage.config({
678 | name: 'kim',
679 | storeName: "kim",
680 | });
681 | }
682 | private keymsg(id: Long): string {
683 | return `msg_${id.toString()}`
684 | }
685 | private keylast(): string {
686 | return `last_id`
687 | }
688 | // 记录一条消息
689 | async insert(msg: Message): Promise {
690 | await localforage.setItem(this.keymsg(msg.messageId), msg)
691 | return true
692 | }
693 | // 检查消息是否已经保存
694 | async exist(id: Long): Promise {
695 | try {
696 | let val = await localforage.getItem(this.keymsg(id))
697 | return !!val
698 | } catch (err) {
699 | log.warn(err);
700 | }
701 | return false;
702 | }
703 | async get(id: Long): Promise {
704 | try {
705 | let message = await localforage.getItem(this.keymsg(id))
706 | return message
707 | } catch (err) {
708 | log.warn(err);
709 | }
710 | return null
711 | }
712 | async setAck(id: Long): Promise {
713 | await localforage.setItem(this.keylast(), id)
714 | return true
715 | }
716 | async lastId(): Promise {
717 | let id = await localforage.getItem(this.keylast())
718 | return id || Long.ZERO
719 | }
720 | }
721 |
722 | export let Store = new MsgStorage();
--------------------------------------------------------------------------------