diff --git a/client/Connection.ts b/client/Connection.ts index e273f05..c712186 100644 --- a/client/Connection.ts +++ b/client/Connection.ts @@ -6,7 +6,7 @@ import { S2CRequestType, S2CRequestTypes, } from "../protocol"; -import Transport from "./Transport"; +import Transport from "../protocol/Transport"; export default class Connection { callbacks: Record = {}; diff --git a/client/DevWsTransport.ts b/client/DevWsTransport.ts index eb4ffa1..4d11ce7 100644 --- a/client/DevWsTransport.ts +++ b/client/DevWsTransport.ts @@ -1,4 +1,4 @@ -import Transport from "./Transport"; +import Transport from "../protocol/Transport"; export class DevWsTransport extends Transport { ws: WebSocket; diff --git a/client/RTCTransport.ts b/client/RTCTransport.ts index d66e1c5..0267504 100644 --- a/client/RTCTransport.ts +++ b/client/RTCTransport.ts @@ -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) }; } diff --git a/frontend/App.svelte b/frontend/App.svelte index 7d44339..d305388 100644 --- a/frontend/App.svelte +++ b/frontend/App.svelte @@ -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();

diff --git a/package.json b/package.json index f59ffd7..62f460a 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66cfe45..1441c50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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: diff --git a/client/Transport.ts b/protocol/Transport.ts similarity index 100% rename from client/Transport.ts rename to protocol/Transport.ts diff --git a/server/client.ts b/server/client.ts index ae4372c..94d5169 100644 --- a/server/client.ts +++ b/server/client.ts @@ -8,6 +8,7 @@ import { request as httpRequest, } from "http"; +import { Readable } from "stream"; import EventEmitter from "events"; import { diff --git a/server/dev.ts b/server/dev.ts new file mode 100644 index 0000000..e69de29 diff --git a/server/main.ts b/server/main.ts index 27d9ab1..15c09aa 100644 --- a/server/main.ts +++ b/server/main.ts @@ -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) => void -) { + onAnswer: (answer: Record) => void, + +): Promise { 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); + }); }); diff --git a/server/rtc.ts b/server/rtc.ts new file mode 100644 index 0000000..e69de29