Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/browser/mainThreadManagedSockets.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { VSBuffer } from '../../../base/common/buffer.js';
7
import { Emitter } from '../../../base/common/event.js';
8
import { Disposable, IDisposable } from '../../../base/common/lifecycle.js';
9
import { ISocket, SocketCloseEventType } from '../../../base/parts/ipc/common/ipc.net.js';
10
import { ManagedSocket, RemoteSocketHalf, connectManagedSocket } from '../../../platform/remote/common/managedSocket.js';
11
import { ManagedRemoteConnection, RemoteConnectionType } from '../../../platform/remote/common/remoteAuthorityResolver.js';
12
import { IRemoteSocketFactoryService, ISocketFactory } from '../../../platform/remote/common/remoteSocketFactoryService.js';
13
import { ExtHostContext, ExtHostManagedSocketsShape, MainContext, MainThreadManagedSocketsShape } from '../common/extHost.protocol.js';
14
import { IExtHostContext, extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js';
15
16
@extHostNamedCustomer(MainContext.MainThreadManagedSockets)
17
export class MainThreadManagedSockets extends Disposable implements MainThreadManagedSocketsShape {
18
19
private readonly _proxy: ExtHostManagedSocketsShape;
20
private readonly _registrations = new Map<number, IDisposable>();
21
private readonly _remoteSockets = new Map<number, RemoteSocketHalf>();
22
23
constructor(
24
extHostContext: IExtHostContext,
25
@IRemoteSocketFactoryService private readonly _remoteSocketFactoryService: IRemoteSocketFactoryService,
26
) {
27
super();
28
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostManagedSockets);
29
}
30
31
async $registerSocketFactory(socketFactoryId: number): Promise<void> {
32
const that = this;
33
const socketFactory = new class implements ISocketFactory<RemoteConnectionType.Managed> {
34
35
supports(connectTo: ManagedRemoteConnection): boolean {
36
return (connectTo.id === socketFactoryId);
37
}
38
39
connect(connectTo: ManagedRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
40
return new Promise<ISocket>((resolve, reject) => {
41
if (connectTo.id !== socketFactoryId) {
42
return reject(new Error('Invalid connectTo'));
43
}
44
45
const factoryId = connectTo.id;
46
that._proxy.$openRemoteSocket(factoryId).then(socketId => {
47
const half: RemoteSocketHalf = {
48
onClose: new Emitter(),
49
onData: new Emitter(),
50
onEnd: new Emitter(),
51
};
52
that._remoteSockets.set(socketId, half);
53
54
MainThreadManagedSocket.connect(socketId, that._proxy, path, query, debugLabel, half)
55
.then(
56
socket => {
57
socket.onDidDispose(() => that._remoteSockets.delete(socketId));
58
resolve(socket);
59
},
60
err => {
61
that._remoteSockets.delete(socketId);
62
reject(err);
63
});
64
}).catch(reject);
65
});
66
}
67
};
68
this._registrations.set(socketFactoryId, this._remoteSocketFactoryService.register(RemoteConnectionType.Managed, socketFactory));
69
70
}
71
72
async $unregisterSocketFactory(socketFactoryId: number): Promise<void> {
73
this._registrations.get(socketFactoryId)?.dispose();
74
}
75
76
$onDidManagedSocketHaveData(socketId: number, data: VSBuffer): void {
77
this._remoteSockets.get(socketId)?.onData.fire(data);
78
}
79
80
$onDidManagedSocketClose(socketId: number, error: string | undefined): void {
81
this._remoteSockets.get(socketId)?.onClose.fire({
82
type: SocketCloseEventType.NodeSocketCloseEvent,
83
error: error ? new Error(error) : undefined,
84
hadError: !!error
85
});
86
this._remoteSockets.delete(socketId);
87
}
88
89
$onDidManagedSocketEnd(socketId: number): void {
90
this._remoteSockets.get(socketId)?.onEnd.fire();
91
}
92
}
93
94
export class MainThreadManagedSocket extends ManagedSocket {
95
public static connect(
96
socketId: number,
97
proxy: ExtHostManagedSocketsShape,
98
path: string, query: string, debugLabel: string,
99
half: RemoteSocketHalf
100
): Promise<MainThreadManagedSocket> {
101
const socket = new MainThreadManagedSocket(socketId, proxy, debugLabel, half);
102
return connectManagedSocket(socket, path, query, debugLabel, half);
103
}
104
105
private constructor(
106
private readonly socketId: number,
107
private readonly proxy: ExtHostManagedSocketsShape,
108
debugLabel: string,
109
half: RemoteSocketHalf,
110
) {
111
super(debugLabel, half);
112
}
113
114
public override write(buffer: VSBuffer): void {
115
this.proxy.$remoteSocketWrite(this.socketId, buffer);
116
}
117
118
protected override closeRemote(): void {
119
this.proxy.$remoteSocketEnd(this.socketId);
120
}
121
122
public override drain(): Promise<void> {
123
return this.proxy.$remoteSocketDrain(this.socketId);
124
}
125
}
126
127