Spaces:
Sleeping
Sleeping
File size: 2,693 Bytes
4cadbaf |
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
import path from "path";
import websocket from "websocket";
// eslint-disable-next-line
import { Server } from "net";
import FileProxy from "./fileProxy";
import { command } from "yargs";
interface ServerOptions {
rootDir: string;
};
const acceptFrontendConnection = (request, options: ServerOptions) => {
const connection = request.accept("editor-frontend", request.origin);
console.log("[web-editor] frontend accepted:", request.origin, connection.remoteAddress);
let file = null;
connection.on("close", (reasonCode, description) => {
console.log("[web-editor] frontend quit:", connection.remoteAddress, reasonCode, description);
if (file) {
file.dispose();
file = null;
}
});
const sendCommand = (command: string, data: object) => connection.sendUTF(JSON.stringify({
command,
...data,
}));
connection.on("message", message => {
const json = JSON.parse(message.utf8Data);
switch (json.command) {
case "bindFile":
try {
const filePath = path.resolve(options.rootDir, json.filePath);
file = new FileProxy(filePath);
file.on("error", err => sendCommand("failure", err));
file.on("fullSync", data => sendCommand("fullSync", data));
file.on("increase", data => sendCommand("increase", data));
}
catch (err) {
console.warn("bindFile failed:", err);
connection.sendUTF(JSON.stringify({ command: "failure", description: err.toString() }));
}
break;
case "increase":
if (!file)
sendCommand("failure", {description: "no file bound yet"});
else {
file.increase({
timestamp: json.timestamp,
fromHash: json.fromHash,
toHash: json.toHash,
patch: json.patch,
});
}
break;
case "requestFullSync":
if (!file)
sendCommand("failure", {description: "no file bound yet"});
else {
console.assert(json.timestamp < file.timestamp, "[web-editor] requestFullSync sent from a newer peer:", new Date(json.timestamp), new Date(file.timestamp));
file.fullSync();
}
break;
default:
console.warn("[web-editor] unexpected frontend command:", json);
}
});
return connection;
};
export function createServer (httpServer: Server, options: ServerOptions) {
const server = new websocket.server({
httpServer,
maxReceivedFrameSize: 0x1000000,
maxReceivedMessageSize: 0x1000000,
closeTimeout: 30e+3,
});
server.on("request", request => {
//console.log("[Synchronizer] request received:", request.origin);
if (request.requestedProtocols.includes("editor-frontend"))
acceptFrontendConnection(request, options);
else
console.warn("Unexpected subprotocol request:", request.origin, request.requestedProtocols);
});
return server;
};
|