1 |
|
2 |
|
3 |
|
4 | import { TextMessageFormat } from "./TextMessageFormat";
|
5 | import { isArrayBuffer } from "./Utils";
|
6 |
|
7 |
|
8 | export interface HandshakeRequestMessage {
|
9 | readonly protocol: string;
|
10 | readonly version: number;
|
11 | }
|
12 |
|
13 |
|
14 | export interface HandshakeResponseMessage {
|
15 | readonly error: string;
|
16 | readonly minorVersion: number;
|
17 | }
|
18 |
|
19 |
|
20 | export class HandshakeProtocol {
|
21 |
|
22 | public writeHandshakeRequest(handshakeRequest: HandshakeRequestMessage): string {
|
23 | return TextMessageFormat.write(JSON.stringify(handshakeRequest));
|
24 | }
|
25 |
|
26 | public parseHandshakeResponse(data: any): [any, HandshakeResponseMessage] {
|
27 | let responseMessage: HandshakeResponseMessage;
|
28 | let messageData: string;
|
29 | let remainingData: any;
|
30 |
|
31 | if (isArrayBuffer(data) || (typeof Buffer !== "undefined" && data instanceof Buffer)) {
|
32 |
|
33 | const binaryData = new Uint8Array(data);
|
34 | const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
|
35 | if (separatorIndex === -1) {
|
36 | throw new Error("Message is incomplete.");
|
37 | }
|
38 |
|
39 |
|
40 |
|
41 | const responseLength = separatorIndex + 1;
|
42 | messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength));
|
43 | remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;
|
44 | } else {
|
45 | const textData: string = data;
|
46 | const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
|
47 | if (separatorIndex === -1) {
|
48 | throw new Error("Message is incomplete.");
|
49 | }
|
50 |
|
51 |
|
52 |
|
53 | const responseLength = separatorIndex + 1;
|
54 | messageData = textData.substring(0, responseLength);
|
55 | remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;
|
56 | }
|
57 |
|
58 |
|
59 | const messages = TextMessageFormat.parse(messageData);
|
60 | const response = JSON.parse(messages[0]);
|
61 | if (response.type) {
|
62 | throw new Error("Expected a handshake response from the server.");
|
63 | }
|
64 | responseMessage = response;
|
65 |
|
66 |
|
67 |
|
68 | return [remainingData, responseMessage];
|
69 | }
|
70 | }
|