Spaces:
Sleeping
Sleeping
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; | |
}; | |