oakserver / oak

A middleware framework for handling HTTP with Deno, Node, Bun and Cloudflare Workers 🐿️ 🦕

Home Page:https://oakserver.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using await inside onmessage callback voids subsequent ws.send calls...

TimHeckel opened this issue · comments

Hi -- appreciate this project very much. I've run into an issue where I can no longer ws.send messages back to the client within the server-side onmessage callback after any attempt to await is used within the callback. The ws.send command works fine when I'm not awaiting. The ws.readyState is 1 (open) after the await finishes, so I'm not sure what is going on.

Below is an example. The second send back is never received by the client, but no errors are thrown. The initial message first send back is received fine. If I remove the await wait(1000); call, then both messages are correctly sent back to the client:

import { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
import { Application, Router } from "https://deno.land/x/oak@v12.1.0/mod.ts";

const app = new Application();
const router = new Router();

async function wait(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("sending back");
      resolve(true);
    }, ms);
  });
}

router.get("/ws", (ctx) => {
  if (!ctx.isUpgradable) {
    ctx.throw(501);
  }
  const ws = ctx.upgrade();
  ws.onmessage = async (msg) => {
    console.log("msg received", msg);
    ws.send("first send back");
    // The next line VOIDS any future use of the ws.send call...
    await wait(1000);
    console.log("should send second");
    ws.send("second send back");
  };
});

app.use(oakCors());
app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port: 8080 });

Perhaps this is known behavior? If so, what is the expected way to await inside an onmessage handler and still be able to ws.send data back to the client?

Thanks for any help on this!

I should also mention that subsequent ws.send calls also do not work even via a callback -- so even avoiding an await has the same effect. Perhaps this behavior is by design and I need to understand the onmessage websocket callback better. At any rate, this is the function that also "voids" any subsequent use of the ws.send method.

function wait2(ms, cb) {
  setTimeout(() => {
    console.log("sending back");
    // ws.send does not work here either
  }, ms);
}

bump - I'd be happy to take a crack at solving this - but hoping for some direction?

FIXED. Upgraded from Deno 1.32.x to Deno 1.34.3. Not sure what was going on, but happy it's now working!