mirror of
https://github.com/MercuryWorkshop/adrift.git
synced 2025-05-17 07:50:00 -04:00
impl client/server version handshake
This commit is contained in:
parent
edd83f54f9
commit
ba77d77036
9 changed files with 114 additions and 10 deletions
|
@ -31,7 +31,10 @@ app.post("/connect", (req, res) => {
|
|||
|
||||
app.ws("/dev-ws", (ws, _req) => {
|
||||
console.log("ws connect");
|
||||
const client = new AdriftServer((msg) => ws.send(msg));
|
||||
const client = new AdriftServer(
|
||||
(msg) => ws.send(msg),
|
||||
() => ws.close()
|
||||
);
|
||||
|
||||
ws.on("message", (msg) => {
|
||||
if (typeof msg === "string") {
|
||||
|
|
|
@ -75,9 +75,12 @@ export async function answerRtc(data: any, onrespond: (answer: any) => void) {
|
|||
|
||||
dataChannel.onopen = () => {
|
||||
console.log("opened");
|
||||
server = new AdriftServer((msg) => {
|
||||
if (dataChannel.readyState === "open") dataChannel.send(msg);
|
||||
});
|
||||
server = new AdriftServer(
|
||||
(msg) => {
|
||||
if (dataChannel.readyState === "open") dataChannel.send(msg);
|
||||
},
|
||||
() => dataChannel.close()
|
||||
);
|
||||
};
|
||||
dataChannel.onclose = () => {
|
||||
console.log("closed");
|
||||
|
|
|
@ -3,12 +3,16 @@ import { IncomingMessage, STATUS_CODES } from "http";
|
|||
import { WebSocket } from "isomorphic-ws";
|
||||
import {
|
||||
C2SRequestTypes,
|
||||
C2S_HELLO,
|
||||
HTTPRequestPayload,
|
||||
HTTPResponsePayload,
|
||||
MAX_CHUNK_SIZE,
|
||||
PROTOCOL_VERSION,
|
||||
ProtoBareHeaders,
|
||||
S2CRequestType,
|
||||
S2CRequestTypes,
|
||||
S2C_HELLO_ERR,
|
||||
S2C_HELLO_OK,
|
||||
WSClosePayload,
|
||||
WSErrorPayload,
|
||||
} from "protocol";
|
||||
|
@ -32,16 +36,41 @@ function bareErrorToResponse(e: BareError): {
|
|||
}
|
||||
|
||||
export class AdriftServer {
|
||||
initialized: boolean = false;
|
||||
send: (msg: ArrayBuffer) => void;
|
||||
close: () => void;
|
||||
requestStreams: Record<number, Promise<Writable>> = {};
|
||||
sockets: Record<number, WebSocket> = {};
|
||||
events: EventEmitter;
|
||||
|
||||
constructor(send: (msg: ArrayBuffer) => void) {
|
||||
constructor(send: (msg: ArrayBuffer) => void, close: () => void) {
|
||||
this.send = send;
|
||||
this.close = close;
|
||||
this.events = new EventEmitter();
|
||||
}
|
||||
|
||||
handleHello(msg: ArrayBuffer) {
|
||||
try {
|
||||
const text = new TextDecoder().decode(msg);
|
||||
if (!text.startsWith(C2S_HELLO)) {
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
// later if we want we can supported multiple versions and run different behavior based
|
||||
// on which we are talking to, might be too much effort idk
|
||||
const version = text.slice(C2S_HELLO.length);
|
||||
if (version === PROTOCOL_VERSION) {
|
||||
this.send(new TextEncoder().encode(S2C_HELLO_OK));
|
||||
this.initialized = true;
|
||||
} else {
|
||||
this.send(new TextEncoder().encode(S2C_HELLO_ERR + PROTOCOL_VERSION));
|
||||
this.close();
|
||||
}
|
||||
} catch (_) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
static parseMsgInit(
|
||||
msg: ArrayBuffer
|
||||
): { cursor: number; seq: number; op: number } | undefined {
|
||||
|
@ -207,6 +236,11 @@ export class AdriftServer {
|
|||
}
|
||||
|
||||
async onMsg(msg: ArrayBuffer) {
|
||||
if (!this.initialized) {
|
||||
this.handleHello(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
const init = AdriftServer.parseMsgInit(msg);
|
||||
if (!init) return;
|
||||
const { cursor, seq, op } = init;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue