oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.42k stars 2.78k forks source link

websocket - potential bug, weird behavior with ping/pong, maybe I'm missing something #5588

Closed robobun closed 2 months ago

robobun commented 1 year ago

minimal reproducible

const server = Bun.serve({
    fetch(req) {
        console.log('SERVER incoming request');
        server.upgrade(req);
    },
    websocket: {
        open(ws) {
            console.log(`SERVER open`);
            ws.ping(); // removing this fixes the issue - this is probably the buggy part
        },
        close(ws, code, reason) {
            console.log(`SERVER close: code=${code} reason=${reason}`);
        },
        message(ws, message) {
            console.log(`SERVER message: ${Bun.inspect(message)}`);
        }
    },
    port: 1337,
});

const ws = new WebSocket('ws://127.0.0.1:1337');

ws.onopen = async () => { // same behavior with addEventHandler
    ws.send('this message sends just fine');

    for await (const _ of console) { // removing this fixes the issue
        ws.send('hi'); // causes closure upon first line
    }
};

output with code shown above

% bun run index.js
SERVER incoming request
SERVER open
SERVER message: "this message sends just fine"

output with server ws.ping() or client for await (...) excluded

% bun run index.js
SERVER incoming request
SERVER open
SERVER message: "this message sends just fine"
  <-- ENTER (for await over console)
SERVER close: code=1006 reason=

I haven't a clue what's actually causing this, but the presence or absence of a ping doesn't seem like it should cause any problems. I previously had handlers for ping/pong messages, I was just testing them out (no intervals yet), but the issue was there before as well - I tried to reduce the fluff as much as possible to get a simple reproducible

Originally reported on Discord: websocket - potential bug, weird behavior with ping/pong, maybe I'm missing something

DeveloperHarris commented 1 year ago

Encountering this issue as well. The bun websocket client seems to have a bug in regards to receiving pings that causes the connection to close?

I also have a simple ServerWebSocket setup and a WebSocket like you, and am able to get some intervaled pings to work, but not others.

ping("42") for example works, but ping() or ping("hello") does not.

Very strange.

// Server
let timer;

Bun.serve({
    fetch(req, server) {
        // upgrade the request to a WebSocket
        if (server.upgrade(req)) {
            return; // do not return a Response
        }
        return new Response("Upgrade failed :(", { status: 500 });
    },
    websocket: {
        open(ws) {
            timer = setInterval(() => {
                console.log("server tx'd ping. ");
                ws.ping("test");
            }, 2000);
        },
        message(ws, message) {
            let hexString = message.toString("hex");
            let hexWithSpaces = hexString.match(/.{1,2}/g)!.join(" ");
            console.log("server rx'd:", hexWithSpaces);
        },
        close(ws, code, message) {
            console.log("server closed:", code, message);
            clearInterval(timer!);
        },
    },
});

// Client
const socket = new WebSocket("ws://localhost:3000");

socket.addEventListener("message", (event) => {
    console.log("client rx'd:", event.data);
});

socket.addEventListener("error", (event) => {
    console.error("client error:", event);
});

socket.addEventListener("close", (event) => {
    console.log("client close:", event.code, event.reason);
});

ws.ping("test") fails:

server tx'd ping.
server closed: 1006
client close: 1006 Connection ended

but ws.ping("42") works:

server tx'd ping.
server tx'd ping.
server rx'd: 34 32 b6 67 88 c1 5c 13 bc f3
server tx'd ping.
server tx'd ping.
server rx'd: 34 32 4b f3 7a 4d bf ba 4e 7f
Jarred-Sumner commented 2 months ago

Bun's websocket client passes the autobahn test suite some time after this PR, and I'm no longer able to reproduce the client closing unexpectedly

If you still run into this issue, please let us know.

pantemon commented 2 weeks ago

@Jarred-Sumner hey the code from https://github.com/oven-sh/bun/issues/5588#issuecomment-1760546789 doesn't produce the same logs. Ping is not received on the client. idleTimeout doesn't work either.