Skip to content

Commit 924f644

Browse files
committed
feat: add TailchatWsClient and update tailchat-types
1 parent 22f08c9 commit 924f644

File tree

13 files changed

+233
-35
lines changed

13 files changed

+233
-35
lines changed

client/packages/tailchat-client-sdk/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tailchat-client-sdk",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"description": "",
55
"main": "lib/index.js",
66
"scripts": {
@@ -16,9 +16,12 @@
1616
"@types/node": "^18.16.1",
1717
"jest": "27.5.1",
1818
"ts-jest": "27.1.4",
19+
"tailchat-types": "*",
1920
"typescript": "^4.9.5"
2021
},
2122
"dependencies": {
22-
"axios": "^1.3.2"
23+
"axios": "^1.3.2",
24+
"socket.io-client": "^4.7.1",
25+
"socket.io-msgpack-parser": "^3.0.2"
2326
}
2427
}

client/packages/tailchat-client-sdk/src/openapi/client.ts renamed to client/packages/tailchat-client-sdk/src/openapi/client/base.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import axios, { AxiosInstance } from 'axios';
22
import crypto from 'crypto';
33

4-
export class TailchatClient {
4+
export class TailchatBaseClient {
55
request: AxiosInstance;
66
jwt: string | null = null;
77
userId: string | null = null;
@@ -58,16 +58,20 @@ export class TailchatClient {
5858
}
5959
}
6060

61+
async waitingForLogin(): Promise<void> {
62+
await Promise.resolve(this.loginP);
63+
}
64+
6165
async call(action: string, params = {}) {
6266
try {
63-
await Promise.resolve(this.loginP);
67+
await this.waitingForLogin();
6468
console.log('Calling:', action);
6569
const { data } = await this.request.post(
6670
'/api/' + action.replace(/\./g, '/'),
6771
params
6872
);
6973

70-
return data;
74+
return data.data;
7175
} catch (err: any) {
7276
console.error('Service Call Failed:', err);
7377
const data: string = err?.response?.data;
@@ -84,7 +88,18 @@ export class TailchatClient {
8488
}
8589
}
8690

87-
async whoami() {
91+
async whoami(): Promise<{
92+
userAgent: string;
93+
language: string;
94+
user: {
95+
_id: string;
96+
nickname: string;
97+
email: string;
98+
avatar: string;
99+
};
100+
token: string;
101+
userId: string;
102+
}> {
88103
return this.call('user.whoami');
89104
}
90105

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { TailchatBaseClient } from './base';
2+
3+
export class TailchatHTTPClient extends TailchatBaseClient {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export {
2+
/**
3+
* @deprecated please rename to TailchatHTTPClient
4+
*/
5+
TailchatHTTPClient as TailchatClient,
6+
TailchatHTTPClient,
7+
} from './http';
8+
export { TailchatWsClient } from './ws';
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { TailchatBaseClient } from './base';
2+
import io, { Socket } from 'socket.io-client';
3+
import * as msgpackParser from 'socket.io-msgpack-parser';
4+
import type { ChatMessage } from 'tailchat-types';
5+
6+
export class TailchatWsClient extends TailchatBaseClient {
7+
public socket: Socket | null = null;
8+
9+
connect(): Promise<Socket> {
10+
return new Promise<Socket>(async (resolve, reject) => {
11+
await this.waitingForLogin();
12+
13+
const token = this.jwt;
14+
15+
const socket = (this.socket = io(this.url, {
16+
transports: ['websocket'],
17+
auth: {
18+
token,
19+
},
20+
forceNew: true,
21+
parser: msgpackParser,
22+
}));
23+
24+
socket.once('connect', () => {
25+
// 连接成功
26+
this.emit('chat.converse.findAndJoinRoom')
27+
.then((res) => {
28+
console.log('Joined rooms', res.data);
29+
resolve(socket);
30+
})
31+
.catch((err) => {
32+
reject(err);
33+
});
34+
});
35+
socket.once('error', () => {
36+
reject();
37+
});
38+
39+
socket.on('disconnect', (reason) => {
40+
console.log(`disconnect due to ${reason}`);
41+
this.socket = null;
42+
});
43+
44+
socket.onAny((ev) => {
45+
console.log('onAny', ev);
46+
});
47+
});
48+
}
49+
50+
disconnect() {
51+
if (!this.socket) {
52+
console.warn('You should call it after connect');
53+
return;
54+
}
55+
56+
this.socket.disconnect();
57+
this.socket = null;
58+
}
59+
60+
emit(eventName: string, eventData: any = {}) {
61+
if (!this.socket) {
62+
console.warn('You should call it after connect');
63+
throw new Error('You should call it after connect');
64+
}
65+
66+
return this.socket.emitWithAck(eventName, eventData);
67+
}
68+
69+
on(eventName: string, callback: (payload: any) => void) {
70+
if (!this.socket) {
71+
console.warn('You should call it after connect');
72+
return;
73+
}
74+
75+
this.socket.on(eventName, callback);
76+
}
77+
78+
once(eventName: string, callback: (payload: any) => void) {
79+
if (!this.socket) {
80+
console.warn('You should call it after connect');
81+
return;
82+
}
83+
84+
this.socket.once(eventName, callback);
85+
}
86+
87+
off(eventName: string, callback: (payload: any) => void) {
88+
if (!this.socket) {
89+
console.warn('You should call it after connect');
90+
return;
91+
}
92+
93+
this.socket.off(eventName, callback);
94+
}
95+
96+
onMessage(callback: (messagePayload: ChatMessage) => void) {
97+
this.on('notify:chat.message.add', callback);
98+
}
99+
100+
onMessageUpdate(callback: (messagePayload: ChatMessage) => void) {
101+
this.on('notify:chat.message.update', callback);
102+
}
103+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { TailchatWsClient } from '../src';
2+
3+
const HOST = process.env.HOST;
4+
const APPID = process.env.APPID;
5+
const APPSECRET = process.env.APPSECRET;
6+
7+
if (!HOST || !APPID || !APPSECRET) {
8+
console.log('require env: HOST, APPID, APPSECRET');
9+
process.exit(1);
10+
}
11+
12+
const client = new TailchatWsClient(HOST, APPID, APPSECRET);
13+
14+
client.connect().then(async () => {
15+
console.log('Login Success!');
16+
17+
client.onMessage((message) => {
18+
console.log('Receive message', message);
19+
});
20+
});

client/packages/tailchat-client-sdk/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"compilerOptions": {
33
"target": "esnext",
44
"lib": ["ESNext"],
5+
"skipLibCheck": true,
56
"outDir": "lib",
67
"declaration": true,
78
"declarationMap": true,

client/shared/model/message.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,7 @@
11
import { request } from '../api/request';
2+
import type { ChatMessageReaction, ChatMessage } from 'tailchat-types';
23

3-
export interface ChatMessageReaction {
4-
name: string;
5-
author: string;
6-
}
7-
8-
export interface ChatMessage {
9-
_id: string;
10-
11-
content: string;
12-
13-
author?: string;
14-
15-
groupId?: string;
16-
17-
converseId: string;
18-
19-
reactions?: ChatMessageReaction[];
20-
21-
hasRecall?: boolean;
22-
23-
meta?: Record<string, unknown>;
24-
25-
createdAt?: string;
26-
27-
updatedAt?: string;
28-
}
4+
export { ChatMessageReaction, ChatMessage };
295

306
export interface SimpleMessagePayload {
317
groupId?: string;

packages/types/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tailchat-types",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"description": "Tailchat model types",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",

packages/types/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './model/inbox';
22
export * from './model/user';
3+
export * from './model/message';

0 commit comments

Comments
 (0)