aboutsummaryrefslogtreecommitdiff
path: root/source/server/index.ts
blob: bac2ffbf16fef83fafb93c21664831bf173e3b29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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();