add rtc server support

This commit is contained in:
CoolElectronics 2023-08-12 13:12:58 -04:00
parent 7ec14853f2
commit 4cc21f0f3b
No known key found for this signature in database
GPG key ID: F63593D168636C50
11 changed files with 78 additions and 25 deletions

View file

@ -6,7 +6,7 @@ import {
S2CRequestType,
S2CRequestTypes,
} from "../protocol";
import Transport from "./Transport";
import Transport from "../protocol/Transport";
export default class Connection {
callbacks: Record<number, Function> = {};

View file

@ -1,4 +1,4 @@
import Transport from "./Transport";
import Transport from "../protocol/Transport";
export class DevWsTransport extends Transport {
ws: WebSocket;

View file

@ -1,4 +1,4 @@
import Transport from "./Transport";
import Transport from "../protocol/Transport";
import Connection from "./Connection";
const rtcConf = {
@ -54,8 +54,9 @@ export class RTCTransport extends Transport {
this.dataChannel.onopen = onopen;
this.dataChannel.onclose = onclose;
this.dataChannel.onmessage = (event) => {
this.ondata(event.data)
this.dataChannel.onmessage = async (event) => {
let buf = await event.data.arrayBuffer();
this.ondata(buf)
};
}

View file

@ -3,9 +3,9 @@
import Connection from "../client/Connection";
import { DevWsTransport } from "../client/DevWsTransport";
import { RTCTransport } from "../client/RTCTransport";
import type Transport from "../client/Transport";
// note: even though we import firebase, due to the tree shaking, it will only run if we use "auth" so if ADRIFT_DEV is set it won't import
import { auth } from "../firebase-config";
import type Transport from "../protocol/Transport";
import {
BareClient,
registerRemoteListener,
@ -80,6 +80,24 @@
}
});
}
async function connectDevHttp() {
let offer = await rtctransport?.createOffer();
console.log("offer created", offer);
console.log(JSON.stringify(offer));
const r = await fetch("http://localhost:3000/connect", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(offer),
});
if (r.status != 200) {
throw new Error("connect: " + r.status + " " + r.statusText);
}
const { answer, candidates } = await r.json();
await rtctransport?.answer(answer, candidates);
}
connectDevHttp();
</script>
<h1>

View file

@ -16,6 +16,7 @@
"@digitak/esrun": "^3.2.24",
"@sveltejs/vite-plugin-svelte": "^2.4.5",
"@tomphttp/bare-client": "^2.2.0-alpha",
"@types/webrtc": "^0.0.36",
"bare-client-custom": "file:bare-client-custom",
"corium": "file:corium",
"dotenv": "^16.3.1",

7
pnpm-lock.yaml generated
View file

@ -14,6 +14,9 @@ dependencies:
'@tomphttp/bare-client':
specifier: ^2.2.0-alpha
version: 2.2.0-alpha
'@types/webrtc':
specifier: ^0.0.36
version: 0.0.36
bare-client-custom:
specifier: file:bare-client-custom
version: file:bare-client-custom
@ -3018,6 +3021,10 @@ packages:
resolution: {integrity: sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==}
dev: false
/@types/webrtc@0.0.36:
resolution: {integrity: sha512-tYFarc92EluXU7XyRmWbkQXSbZIOHTdDOudFPal9u/TNTQuouWpIHV/2o9bNAdqvTJFjLJh/zflCOLWbL30tEQ==}
dev: false
/@types/ws@8.5.5:
resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==}
dependencies:

View file

@ -8,6 +8,7 @@ import {
request as httpRequest,
} from "http";
import { Readable } from "stream";
import EventEmitter from "events";
import {

0
server/dev.ts Normal file
View file

View file

@ -2,7 +2,7 @@ import dotenv from "dotenv";
import express from "express";
import expressWs from "express-ws";
import * as wrtc from "wrtc";
import wrtc from "wrtc";
import { Client } from "./client.js";
const configuration = {
@ -17,24 +17,18 @@ dotenv.config();
async function connect(
offer,
candidates,
onAnswer: (answer: Record<string, any>) => void
) {
onAnswer: (answer: Record<string, any>) => void,
): Promise<RTCDataChannel> {
const localCandidates: any[] = [];
let dataChannel;
const peer = new wrtc.RTCPeerConnection(configuration);
peer.ondatachannel = (event) => {
dataChannel = event.channel;
dataChannel.onopen = () => {
console.log("opened");
let promise = new Promise((resolve) => {
peer.ondatachannel = (event) => {
dataChannel = event.channel;
resolve(dataChannel);
};
dataChannel.onclose = (event) => {
console.log("closed");
};
dataChannel.onmessage = (event) => {
console.log("messaged");
console.log(event);
};
};
});
peer.onconnectionstatechange = () => {
console.log("Connection state:", peer.connectionState);
};
@ -67,6 +61,8 @@ async function connect(
console.log({ candidate });
await peer.addIceCandidate(candidate);
}
return promise as any;
}
const app = express() as unknown as expressWs.Application;
@ -82,18 +78,47 @@ app.use((req, res, next) => {
next();
});
app.post("/connect", (req, res) => {
const data = req.body;
async function answerRtc(data: any, onrespond: (answer: any) => void) {
if (data && data.offer && data.localCandidates) {
const { offer, localCandidates } = data;
let didAnswer = false;
connect(offer, localCandidates, (answer) => {
let dataChannel = await connect(offer, localCandidates, (answer) => {
if (!didAnswer) {
didAnswer = true;
res.json(answer);
onrespond(answer);
// res.json(answer);
}
});
let client: Client;
dataChannel.onopen = () => {
console.log("opened");
client = new Client((msg) => dataChannel.send(msg));
};
dataChannel.onclose = (event) => {
console.log("closed");
client.onClose();
};
dataChannel.onmessage = (event) => {
console.log("messaged");
client.onMsg(Buffer.from(event.data));
};
}
}
app.post("/connect", (req, res) => {
const data = req.body;
answerRtc(data, (d) => {
res.json(d);
});
});

0
server/rtc.ts Normal file
View file