forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocketCallbackHandler.ts
More file actions
86 lines (69 loc) · 2.35 KB
/
socketCallbackHandler.ts
File metadata and controls
86 lines (69 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"use strict";
import * as net from "net";
import { EventEmitter } from "events";
import { SocketStream } from "./SocketStream";
import { SocketServer } from './socketServer';
export abstract class SocketCallbackHandler extends EventEmitter {
private _stream: SocketStream = null;
private commandHandlers: Map<string, Function>;
private handeshakeDone: boolean;
constructor(socketServer: SocketServer) {
super();
this.commandHandlers = new Map<string, Function>();
socketServer.on('data', this.onData.bind(this));
}
private onData(socketClient: net.Socket, data: Buffer) {
this.HandleIncomingData(data, socketClient);
}
protected get stream(): SocketStream {
return this._stream;
}
protected SendRawCommand(commandId: Buffer) {
this.stream.Write(commandId);
}
protected registerCommandHandler(commandId: string, handler: Function) {
this.commandHandlers.set(commandId, handler);
}
protected abstract handleHandshake(): boolean;
private HandleIncomingData(buffer: Buffer, socket: net.Socket): boolean {
if (this._stream === null) {
this._stream = new SocketStream(socket, buffer);
}
else {
this._stream.Append(buffer);
}
if (!this.handeshakeDone && !this.handleHandshake()) {
return;
}
this.handeshakeDone = true;
this.HandleIncomingDataFromStream();
return true;
}
public HandleIncomingDataFromStream() {
if (this.stream.Length === 0) {
return;
}
this.stream.BeginTransaction();
let cmd = this.stream.ReadAsciiString(4);
if (this.stream.HasInsufficientDataForReading) {
this.stream.RollBackTransaction();
return;
}
if (this.commandHandlers.has(cmd)) {
const handler = this.commandHandlers.get(cmd);
handler();
}
else {
this.emit("error", `Unhandled command '${cmd}'`);
}
if (this.stream.HasInsufficientDataForReading) {
// Most possibly due to insufficient data
this.stream.RollBackTransaction();
return;
}
this.stream.EndTransaction();
if (this.stream.Length > 0) {
this.HandleIncomingDataFromStream();
}
}
}