aboutsummaryrefslogtreecommitdiff
path: root/source/server
diff options
context:
space:
mode:
authorMetaMuffin <metamuffin@yandex.com>2021-08-02 10:34:36 +0200
committerMetaMuffin <metamuffin@yandex.com>2021-08-02 10:34:36 +0200
commit6d4a9c797edf2bbb75cea6afef109cb457c52641 (patch)
tree1b2e585b9349184d7e6657211d5c164145bd8210 /source/server
downloadkeks-meet-6d4a9c797edf2bbb75cea6afef109cb457c52641.tar
keks-meet-6d4a9c797edf2bbb75cea6afef109cb457c52641.tar.bz2
keks-meet-6d4a9c797edf2bbb75cea6afef109cb457c52641.tar.zst
initial commit
Diffstat (limited to 'source/server')
-rw-r--r--source/server/index.ts108
1 files changed, 108 insertions, 0 deletions
diff --git a/source/server/index.ts b/source/server/index.ts
new file mode 100644
index 0000000..bac2ffb
--- /dev/null
+++ b/source/server/index.ts
@@ -0,0 +1,108 @@
+import Express, { static as estatic, json } from "express";
+import { join } from "path";
+import Webpack from "webpack"
+import WebpackDevMiddleware from "webpack-dev-middleware"
+import { existsSync, readFile, readFileSync } from "fs";
+import http from "http"
+import https from "https"
+import expressWs from "express-ws";
+import { CallDocModel } from "../models";
+
+const call_docs: Map<String, CallDocModel> = new Map()
+
+
+async function main() {
+ const app_e = Express();
+ const app = expressWs(app_e).app
+
+ const webpackConfig = require('../../webpack.config');
+ const compiler = Webpack(webpackConfig)
+ const devMiddleware = WebpackDevMiddleware(compiler, {
+ publicPath: webpackConfig.output.publicPath
+ })
+ app.use("/scripts", devMiddleware)
+
+ app.disable("x-powered-by");
+ app.use(json());
+
+ app.get("/", (req, res) => {
+ res.sendFile(join(__dirname, "../../public/index.html"));
+ });
+
+ app.use("/static", estatic(join(__dirname, "../../public")));
+
+ app.get("/favicon.ico", (req, res) => {
+ res.sendFile(join(__dirname, "../../public/favicon.ico"));
+ });
+
+ app.ws("/offer/:id", (ws, req) => {
+ const id = req.params.id
+ if (call_docs.get(id)) return ws.close(0, "call already running")
+ console.log(`[${id}] offer websocket open`);
+ ws.onclose = () => console.log(`[${id}] offer websocket close`);
+ const doc: CallDocModel = {
+ answered: false,
+ offer_candidates: [],
+ offer: undefined,
+ on_answer: () => { },
+ on_answer_candidate: () => { },
+ on_offer_candidate: () => { },
+ }
+ ws.onmessage = ev => {
+ const s = JSON.parse(ev.data.toString())
+ if (s.offer) {
+ console.log(`[${id}] offer`);
+ doc.offer = s.offer
+ call_docs.set(id, doc)
+ }
+ if (s.candidate) {
+ console.log(`[${id}] offer candidate`);
+ if (doc.answered) doc.on_offer_candidate(s.candidate)
+ else doc.offer_candidates.push(s.candidate)
+ }
+ }
+ doc.on_answer = answer => ws.send(JSON.stringify({ answer }))
+ doc.on_answer_candidate = candidate => ws.send(JSON.stringify({ candidate }))
+ })
+
+ app.ws("/answer/:id", (ws, req) => {
+ const id = req.params.id
+ console.log(`[${id}] answer websocket open`);
+ ws.onclose = () => console.log(`[${id}] answer websocket close`);
+ const doc = call_docs.get(id)
+ if (!doc) return ws.close(0, "call not found")
+ if (doc.answered) return ws.close(0, "call already answered")
+ ws.onmessage = ev => {
+ const s = JSON.parse(ev.data.toString())
+ if (s.answer) {
+ console.log(`[${id}] answer`);
+ doc.on_answer(s.answer)
+ }
+ if (s.candidate) {
+ console.log(`[${id}] answer candidate`);
+ doc.on_answer_candidate(s.candidate)
+ }
+ }
+ doc.on_offer_candidate = candidate => ws.send(JSON.stringify({ candidate }))
+ // TODO this is evil
+ setTimeout(() => {
+ ws.send(JSON.stringify({ offer: doc.offer }))
+ for (const candidate of doc.offer_candidates) {
+ ws.send(JSON.stringify({ candidate }))
+ }
+ doc.offer_candidates = []
+ }, 100)
+ })
+
+ app.use((req, res, next) => {
+ res.status(404);
+ res.send("This is an error page");
+ });
+
+ const port = parseInt(process.env.PORT ?? "8080")
+ app.listen(port, process.env.HOST ?? "127.0.0.1", () => {
+ console.log(`Server listening on 127.0.0.1:${port}`);
+ })
+}
+
+main(); \ No newline at end of file