code-server/connection.ts

70 lines
2.1 KiB
TypeScript
Raw Normal View History

2019-06-28 22:37:23 +00:00
import { ClientConnectionEvent } from "vs/base/parts/ipc/common/ipc";
import { ConnectionType } from "vs/platform/remote/common/remoteAgentConnection";
2019-06-27 22:34:33 +00:00
import { Emitter } from "vs/base/common/event";
import { PersistentProtocol, ISocket } from "vs/base/parts/ipc/common/ipc.net";
import { VSBuffer } from "vs/base/common/buffer";
2019-06-28 22:37:23 +00:00
export interface Server {
readonly _onDidClientConnect: Emitter<ClientConnectionEvent>;
readonly connections: Map<ConnectionType, Map<string, Connection>>;
}
2019-06-27 22:34:33 +00:00
export abstract class Connection {
2019-06-28 22:37:23 +00:00
private readonly _onClose = new Emitter<void>();
2019-06-27 22:34:33 +00:00
public readonly onClose = this._onClose.event;
2019-06-28 22:37:23 +00:00
private timeout: NodeJS.Timeout | undefined;
private readonly wait = 1000 * 60 * 60;
public constructor(
protected readonly server: Server,
private readonly protocol: PersistentProtocol,
) {
// onClose seems to mean we want to disconnect, so dispose immediately.
this.protocol.onClose(() => this.dispose());
// If the socket closes, we want to wait before disposing so we can
// reconnect.
2019-06-27 22:34:33 +00:00
this.protocol.onSocketClose(() => {
2019-06-28 22:37:23 +00:00
this.timeout = setTimeout(() => {
this.dispose();
}, this.wait);
2019-06-27 22:34:33 +00:00
});
}
2019-06-28 22:37:23 +00:00
/**
* Completely close and clean up the connection. Should only do this once we
* don't need or want the connection. It cannot be re-used after this.
*/
public dispose(): void {
this.protocol.sendDisconnect();
this.protocol.getSocket().end();
this.protocol.dispose();
this._onClose.fire();
}
2019-06-27 22:34:33 +00:00
public reconnect(socket: ISocket, buffer: VSBuffer): void {
2019-06-28 22:37:23 +00:00
clearTimeout(this.timeout as any); // Not sure why the type doesn't work.
2019-06-27 22:34:33 +00:00
this.protocol.beginAcceptReconnection(socket, buffer);
this.protocol.endAcceptReconnection();
}
}
2019-06-28 22:37:23 +00:00
/**
* The management connection is used for all the IPC channels.
*/
2019-06-27 22:34:33 +00:00
export class ManagementConnection extends Connection {
2019-06-28 22:37:23 +00:00
public constructor(server: Server, protocol: PersistentProtocol) {
super(server, protocol);
// This will communicate back to the IPCServer that a new client has
// connected.
this.server._onDidClientConnect.fire({
protocol,
onDidClientDisconnect: this.onClose,
});
}
2019-06-27 22:34:33 +00:00
}
export class ExtensionHostConnection extends Connection {
}