@opensumi/ide-connection 2.21.13-rc-1673328992.0 → 2.21.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,224 +0,0 @@
1
- import pathMatch from 'path-match';
2
- import ws from 'ws';
3
-
4
- import { stringify, parse } from '../common/utils';
5
- import { WSChannel, ChannelMessage } from '../common/ws-channel';
6
-
7
- import { WebSocketHandler, CommonChannelHandlerOptions } from './ws';
8
-
9
- export interface IPathHander {
10
- dispose: (connection: any, connectionId: string) => void;
11
- handler: (connection: any, connectionId: string, params?: any) => void;
12
- reconnect?: (connection: any, connectionId: string) => void;
13
- connection?: any;
14
- }
15
-
16
- export class CommonChannelPathHandler {
17
- private handlerMap: Map<string, IPathHander[]> = new Map();
18
- private paramsKey: Map<string, string> = new Map();
19
-
20
- register(channelPath: string, handler: IPathHander) {
21
- const paramsIndex = channelPath.indexOf('/:');
22
- const hasParams = paramsIndex >= 0;
23
- let channelToken = channelPath;
24
- if (hasParams) {
25
- channelToken = channelPath.slice(0, paramsIndex);
26
- this.paramsKey.set(channelToken, channelPath.slice(paramsIndex + 2));
27
- }
28
- if (!this.handlerMap.has(channelToken)) {
29
- this.handlerMap.set(channelToken, []);
30
- }
31
- const handlerArr = this.handlerMap.get(channelToken) as IPathHander[];
32
- const handlerFn = handler.handler.bind(handler);
33
- const setHandler = (connection, clientId, params) => {
34
- handler.connection = connection;
35
- handlerFn(connection, clientId, params);
36
- };
37
- handler.handler = setHandler;
38
- handlerArr.push(handler);
39
- this.handlerMap.set(channelToken, handlerArr);
40
- }
41
- getParams(channelPath: string, value: string) {
42
- const params = {};
43
- if (this.paramsKey.has(channelPath)) {
44
- const key = this.paramsKey.get(channelPath);
45
- if (key) {
46
- params[key] = value;
47
- }
48
- }
49
- return params;
50
- }
51
- removeHandler(channelPath: string, handler: IPathHander) {
52
- const paramsIndex = channelPath.indexOf(':');
53
- const hasParams = paramsIndex >= 0;
54
- let channelToken = channelPath;
55
- if (hasParams) {
56
- channelToken = channelPath.slice(0, paramsIndex);
57
- }
58
- const handlerArr = this.handlerMap.get(channelToken) || [];
59
- const removeIndex = handlerArr.indexOf(handler);
60
- if (removeIndex !== -1) {
61
- handlerArr.splice(removeIndex, 1);
62
- }
63
- this.handlerMap.set(channelPath, handlerArr);
64
- }
65
- get(channelPath: string) {
66
- return this.handlerMap.get(channelPath);
67
- }
68
- disposeConnectionClientId(connection: ws, clientId: string) {
69
- this.handlerMap.forEach((handlerArr: IPathHander[]) => {
70
- handlerArr.forEach((handler: IPathHander) => {
71
- handler.dispose(connection, clientId);
72
- });
73
- });
74
- }
75
- getAll() {
76
- return Array.from(this.handlerMap.values());
77
- }
78
- }
79
-
80
- export const commonChannelPathHandler = new CommonChannelPathHandler();
81
-
82
- // 后台 Web 链接处理类
83
- export class CommonChannelHandler extends WebSocketHandler {
84
- static channelId = 0;
85
-
86
- public handlerId = 'common-channel';
87
- private wsServer: ws.Server;
88
- protected handlerRoute: (wsPathname: string) => any;
89
- private channelMap: Map<string | number, WSChannel> = new Map();
90
- private connectionMap: Map<string, ws> = new Map();
91
- private heartbeatMap: Map<string, NodeJS.Timeout> = new Map();
92
-
93
- constructor(routePath: string, private logger: any = console, private options: CommonChannelHandlerOptions = {}) {
94
- super();
95
- const route = pathMatch(options.pathMatchOptions);
96
- this.handlerRoute = route(`${routePath}`);
97
- this.initWSServer();
98
- }
99
- private hearbeat(connectionId: string, connection: ws) {
100
- const timer = global.setTimeout(() => {
101
- connection.ping();
102
- // console.log(`connectionId ${connectionId} ping`);
103
- this.hearbeat(connectionId, connection);
104
- }, 5000);
105
-
106
- this.heartbeatMap.set(connectionId, timer);
107
- }
108
-
109
- private initWSServer() {
110
- this.logger.log('init Common Channel Handler');
111
- this.wsServer = new ws.Server({
112
- noServer: true,
113
- ...this.options.wsServerOptions,
114
- });
115
- this.wsServer.on('connection', (connection: ws) => {
116
- let connectionId;
117
- connection.on('message', (msg: string) => {
118
- let msgObj: ChannelMessage;
119
- try {
120
- msgObj = parse(msg);
121
-
122
- // 心跳消息
123
- if (msgObj.kind === 'heartbeat') {
124
- connection.send(stringify(`heartbeat ${msgObj.clientId}`));
125
- } else if (msgObj.kind === 'client') {
126
- const clientId = msgObj.clientId;
127
- this.logger.log(`New connection with id ${clientId}`);
128
- connectionId = clientId;
129
- this.connectionMap.set(clientId, connection);
130
- this.hearbeat(connectionId, connection);
131
- // channel 消息处理
132
- } else if (msgObj.kind === 'open') {
133
- const channelId = msgObj.id; // CommonChannelHandler.channelId ++;
134
- const { path } = msgObj;
135
- this.logger.log(`Open a new connection channel ${channelId} with path ${path}`);
136
-
137
- // 生成 channel 对象
138
- const connectionSend = this.channelConnectionSend(connection);
139
- const channel = new WSChannel(connectionSend, channelId);
140
- this.channelMap.set(channelId, channel);
141
-
142
- // 根据 path 拿到注册的 handler
143
- let handlerArr = commonChannelPathHandler.get(path);
144
- let params;
145
- // 尝试通过父路径查找处理函数,如server/:id方式注册的handler
146
- if (!handlerArr) {
147
- const slashIndex = path.indexOf('/');
148
- const hasSlash = slashIndex >= 0;
149
- if (hasSlash) {
150
- handlerArr = commonChannelPathHandler.get(path.slice(0, slashIndex));
151
- params = commonChannelPathHandler.getParams(path.slice(0, slashIndex), path.slice(slashIndex + 1));
152
- }
153
- }
154
-
155
- if (handlerArr) {
156
- for (let i = 0, len = handlerArr.length; i < len; i++) {
157
- const handler = handlerArr[i];
158
- handler.handler(channel, connectionId, params);
159
- }
160
- }
161
-
162
- channel.ready();
163
- } else {
164
- const { id } = msgObj;
165
- const channel = this.channelMap.get(id);
166
- if (channel) {
167
- channel.handleMessage(msgObj);
168
- } else {
169
- this.logger.warn(`The channel(${id}) was not found`);
170
- }
171
- }
172
- } catch (e) {
173
- this.logger.warn(e);
174
- }
175
- });
176
-
177
- connection.on('close', () => {
178
- commonChannelPathHandler.disposeConnectionClientId(connection, connectionId as string);
179
-
180
- if (this.heartbeatMap.has(connectionId)) {
181
- clearTimeout(this.heartbeatMap.get(connectionId) as NodeJS.Timeout);
182
- this.heartbeatMap.delete(connectionId);
183
-
184
- this.logger.verbose(`Clear heartbeat from channel ${connectionId}`);
185
- }
186
-
187
- Array.from(this.channelMap.values())
188
- .filter((channel) => channel.id.toString().indexOf(connectionId) !== -1)
189
- .forEach((channel) => {
190
- channel.close(1, 'close');
191
- this.channelMap.delete(channel.id);
192
- this.logger.verbose(`Remove connection channel ${channel.id}`);
193
- });
194
- });
195
- });
196
- }
197
-
198
- private channelConnectionSend = (connection: ws) => (content: string) => {
199
- if (connection.readyState === connection.OPEN) {
200
- connection.send(content, (err: any) => {
201
- if (err) {
202
- this.logger.log(err);
203
- }
204
- });
205
- }
206
- };
207
- public handleUpgrade(wsPathname: string, request: any, socket: any, head: any): boolean {
208
- const routeResult = this.handlerRoute(wsPathname);
209
-
210
- if (routeResult) {
211
- const wsServer = this.wsServer;
212
- wsServer.handleUpgrade(request, socket, head, (connection: any) => {
213
- connection.routeParam = {
214
- pathname: wsPathname,
215
- };
216
-
217
- wsServer.emit('connection', connection);
218
- });
219
- return true;
220
- }
221
-
222
- return false;
223
- }
224
- }
@@ -1,11 +0,0 @@
1
- import type net from 'net';
2
-
3
- import {
4
- SocketMessageReader,
5
- SocketMessageWriter,
6
- createMessageConnection,
7
- } from '@opensumi/vscode-jsonrpc/lib/node/main';
8
-
9
- export function createSocketConnection(socket: net.Socket) {
10
- return createMessageConnection(new SocketMessageReader(socket), new SocketMessageWriter(socket));
11
- }
package/src/node/index.ts DELETED
@@ -1,7 +0,0 @@
1
- import { SocketMessageReader, SocketMessageWriter } from '@opensumi/vscode-jsonrpc/lib/node/main';
2
-
3
- export * from './ws';
4
- export * from './common-channel-handler';
5
- export * from './connect';
6
-
7
- export { SocketMessageReader, SocketMessageWriter };
package/src/node/ws.ts DELETED
@@ -1,109 +0,0 @@
1
- import http from 'http';
2
- import url from 'url';
3
-
4
- import ws from 'ws';
5
-
6
- export abstract class WebSocketHandler {
7
- abstract handlerId: string;
8
- abstract handleUpgrade(wsPathname: string, request: any, socket: any, head: any): boolean;
9
- init?(): void;
10
- }
11
-
12
- export interface CommonChannelHandlerOptions {
13
- wsServerOptions?: ws.ServerOptions;
14
- pathMatchOptions?: {
15
- // When true the regexp will match to the end of the string.
16
- end?: boolean;
17
- };
18
- }
19
-
20
- export class WebSocketServerRoute {
21
- public server: http.Server;
22
- public port?: number;
23
- private wsServerHandlerArr: WebSocketHandler[];
24
-
25
- constructor(
26
- server: http.Server,
27
- private logger: any = console,
28
- port = 8729,
29
- wsServerHandlerArr: WebSocketHandler[] = [],
30
- ) {
31
- if (server) {
32
- this.server = server as http.Server;
33
- }
34
-
35
- this.port = port;
36
- this.wsServerHandlerArr = wsServerHandlerArr;
37
- }
38
-
39
- public registerHandler(handler: WebSocketHandler) {
40
- const wsServerHandlerArr = this.wsServerHandlerArr;
41
- const findHandler = (h: WebSocketHandler) => h.handlerId === handler!.handlerId;
42
-
43
- if (wsServerHandlerArr.findIndex(findHandler) === -1) {
44
- this.wsServerHandlerArr.push(handler);
45
- }
46
- }
47
-
48
- public deleteHandler(handler: WebSocketHandler | string) {
49
- let handlerId: string;
50
- if ((handler as WebSocketHandler).handlerId) {
51
- handlerId = (handler as WebSocketHandler).handlerId;
52
- } else {
53
- handlerId = handler as string;
54
- }
55
-
56
- const handlerIndex = this.wsServerHandlerArr.findIndex((handler) => handler.handlerId === handlerId);
57
-
58
- if (handlerIndex !== -1) {
59
- this.wsServerHandlerArr.splice(handlerIndex, 1);
60
- return true;
61
- } else {
62
- return false;
63
- }
64
- }
65
-
66
- public init() {
67
- this.initServer();
68
- this.initHandler();
69
- this.handleUpgrade();
70
- }
71
- private initServer() {
72
- if (!this.server) {
73
- this.server = http.createServer();
74
- this.server.listen(this.port, () => {
75
- this.logger.log(`websocket server listen on ${this.port}`);
76
- });
77
- }
78
- }
79
- private initHandler() {
80
- this.wsServerHandlerArr.forEach((handler) => {
81
- if (handler.init) {
82
- handler.init.call(handler);
83
- }
84
- });
85
- }
86
- private handleUpgrade() {
87
- const server = this.server;
88
- const wsServerHandlerArr = this.wsServerHandlerArr;
89
-
90
- server.on('upgrade', (request, socket, head) => {
91
- const wsPathname: string = url.parse(request.url).pathname as string;
92
-
93
- let wsHandlerIndex = 0;
94
- const wsHandlerLength = wsServerHandlerArr.length;
95
-
96
- for (; wsHandlerIndex < wsHandlerLength; wsHandlerIndex++) {
97
- const handler = wsServerHandlerArr[wsHandlerIndex];
98
- const handleResult = handler.handleUpgrade(wsPathname, request, socket, head);
99
- if (handleResult) {
100
- break;
101
- }
102
- }
103
-
104
- if (wsHandlerIndex === wsHandlerLength) {
105
- this.logger.error(`request.url ${request.url} mismatch!`);
106
- }
107
- });
108
- }
109
- }