瀏覽代碼

wip deferred response

hmt 3 年之前
父節點
當前提交
66c412a1d6
共有 4 個文件被更改,包括 38 次插入7 次删除
  1. 1 1
      README.md
  2. 28 3
      app.ts
  3. 4 1
      bbb.ts
  4. 5 2
      deps.ts

+ 1 - 1
README.md

@@ -25,7 +25,7 @@ Then create a `servers.json` file like this here:
 
 Now you are ready to start the script with setting a port and a secret:
 
-    TINYSCALE_SECRET=some_secret_string deno run --allow-net --allow-read --allow-env https://deno.land/x/tinyscale@v1.5.0/mod.ts
+    TINYSCALE_SECRET=some_secret_string deno run --allow-net --allow-read --allow-env https://deno.land/x/tinyscale@v1.5.1/mod.ts
 
 tinyscale then runs on port 3005 and you will have to set up your reverse proxy so that it can pick up requests or you leave it on that port. If you prefer a different port you can set one with another env var: `PORT 3006`
 

+ 28 - 3
app.ts

@@ -1,8 +1,8 @@
-import { opine, ErrorRequestHandler, Router, createHash, server, createError, Color } from "./deps.ts";
+import { opine, ErrorRequestHandler, Router, createHash, server, createError, Color, deferred, Deferred } from "./deps.ts";
 import { BBB } from './bbb.ts';
 
 const date = () => new Date().toLocaleTimeString('de')
-const VERSION = 'v1.5.0'
+const VERSION = 'v1.5.1'
 // give your tinyscale server a secret so it looks like a BBB server
 const secret: string = Deno.env.get("TINYSCALE_SECRET") || ""
 if (!secret) throw "No secret set for tinyscale"
@@ -37,6 +37,10 @@ servers.forEach(async s => {
 })
 let current_server: server
 get_available_server()
+
+type waiter = Deferred<string>
+type queue = Record<string, waiter>
+let queue: queue = {}
 // pick the next server, using an iterator to cycle through all servers available
 function get_available_server(): server {
   let candidate = iterator.next()
@@ -64,7 +68,7 @@ router.all("/:call", async (req, res, next) => {
     server = await handler.find_meeting_id(servers)
   } catch (e) {
     console.log(`Found no server with Meeting ID ${Color.yellow(handler.meeting_id)}`)
-    if (handler.call === 'create' && tinyscale_strict) get_available_server()
+    if (handler.call === 'create' && tinyscale_strict) { get_available_server() }
     server = current_server
   }
   console.log(`Redirecting to ${server.host}`)
@@ -75,9 +79,11 @@ router.all("/:call", async (req, res, next) => {
     try {
       const data = await fetch(redirect)
       const body = await data.text()
+      if (handler.call === 'create') {queue[handler.meeting_id].resolve(body);delete queue[handler.meeting_id]}
       res.set('Content-Type', 'text/xml');
       res.send(body)
     } catch (e) {
+      if (handler.call === 'create') {queue[handler.meeting_id].reject(Error);delete queue[handler.meeting_id]}
       next(createError(500))
     }
   }
@@ -97,8 +103,27 @@ const errorHandler: ErrorRequestHandler = (err, req, res, next) => {
   res.end();
   console.log(`${Color.red(`${res.status}`)} ${req.originalUrl}`)
 };
+// @ts-ignore
+const check_if_create = async (req, res, next) => {
+  console.log("check if room has been called before and has not yet finished")
+  const meeting_id = req.query.meetingID
+  console.log(meeting_id)
+  const existing_id = queue[meeting_id]
+  console.log(meeting_id, existing_id)
+  if (existing_id) {
+    try {
+      const existing_res = await existing_id
+      console.log(existing_res)
+      res.send(existing_res)
+    } catch (e) { next() }
+  } else {
+    queue[meeting_id] = deferred<string>();
+    next()
+  }
+}
 
 const app = opine()
+  .use('/bigbluebutton/api/create', check_if_create)
   .use("/bigbluebutton/api", router)
   .use((req, res, next) => next(createError(404)))
   .use(errorHandler);

+ 4 - 1
bbb.ts

@@ -1,5 +1,6 @@
-import { Request, ParamsDictionary,  createHash, server } from "./deps.ts";
+import { Request, ParamsDictionary,  createHash } from "./deps.ts";
 
+export interface server { host: string; secret: string };
 export class BBB {
   call: string
   checksum_incoming: string
@@ -39,8 +40,10 @@ export class BBB {
     return ok
   }
   find_meeting_id = (servers: server[]): Promise<server> => {
+    const p1 = new Promise((res) => setTimeout(() => res("p1"), 5000));
     if (!this.meeting_id) throw Error
     const promises = servers.map(async s => {
+      await p1
       const res = await fetch(this.check_for_meeting_query(s))
       if (!res.ok) throw Error
       const text = await res.text()

+ 5 - 2
deps.ts

@@ -1,7 +1,10 @@
-export { join, } from "https://deno.land/std@0.95.0/path/mod.ts";
+export {  deferred } from "https://deno.land/std/async/mod.ts";
+export type { Deferred } from "https://deno.land/std/async/mod.ts";
+export { join } from "https://deno.land/std@0.95.0/path/mod.ts";
 export { createHash } from "https://deno.land/std@0.95.0/hash/mod.ts";
 export * as Color from "https://deno.land/std@0.95.0/fmt/colors.ts";
 export { createError } from "https://deno.land/x/http_errors@3.0.0/mod.ts";
 export { opine, Router } from "https://deno.land/x/opine@1.3.2/mod.ts";
 export type { ErrorRequestHandler, Request, ParamsDictionary } from "https://deno.land/x/opine@1.3.2/mod.ts";
-export interface server { host: string; secret: string };
+export interface server { host: string; secret: string };
+// export type queue = Record<string, deferred<string>()>;