Skip to content

websocket breaks when integrated with frameworK #1092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Th4phat opened this issue Feb 26, 2025 · 7 comments
Open

websocket breaks when integrated with frameworK #1092

Th4phat opened this issue Feb 26, 2025 · 7 comments

Comments

@Th4phat
Copy link

Th4phat commented Feb 26, 2025

os: win 10
bun version: 1.2.2
elysia version: ^1.2.18

So, I'm running into a weird issue which I can't find any solution anywhere.
I'm trying to use Elysia's websockets with Next.js (15.1.7) and Astro (5.3.1), and they just don't want to connect. But, if I run the websocket endpoint with just Elysia, without those frameworks, it works perfectly fine. I'm not sure if this is a bug or just something I'm missing, but I haven't been able to figure it out. I haven't tried Svelte or Expo yet. If anyone has any ideas or knows how to fix this, I'd really appreciate the help.

here's the code I use to test:

.ws("/ws", {
    open(ws) {
      console.log("opennn");
    },
    message(ws, message) {
      ws.send(message);
    },
    close() {
      console.log("close");
    },
  })
@GGAlanSmithee
Copy link

were you able to find a solution to this @Th4phat ?

@ledihildawan
Copy link

I just tried it too, can't connect. Is there something wrong?

@ap0nia
Copy link

ap0nia commented Apr 5, 2025

The first reason is that Elysia's WebSocket functionality only exists in the BunAdapter. You can tell because it has a ws method. When you integrate it with other frameworks, it switches to the web-standard adapter, which does not have a ws method. However, it has a websocket method and maybe it's a typo or unreleased feature.

A second thing to consider is whether Next.js even supports WebSockets. It would probably be helpful to review other people's attempts to use the feature in Next.js in the first place. For example, this blog with Socket.io.

Following up the second point, Elysia would need access to "server-upgrade" requests or equivalent in order to actually detect a WebSocket connection. Based on your framework, you may need to write a custom adapter. For example, based on the WebSocket implementation that SvelteKit is working on, an adapter might look roughly like this psuedo-code. I actually was able to get a rough proof of concept working, but it's definitely non-trivial.

// src/routes/ws/+server.ts

import type { Socket } from '@sveltejs/kit';

const listeners = new Set()

const app = new Elysia({
  adapter: {
    ...WebStandardAdapter,
   ws(app, path, options) {
    listeners.push({
     message: (peer, message) => {
      // handle data before invoking the original message callback, e.g. the one specified in the /ws call .
      // For example, this would be the "message" property defined below that just does console.log
      // Whenever Elysia.ws is called, the adapter.ws method is called to handle the registration.
      options.message(peer, message)
    }
    })
   }
  }
}).ws('/ws', {
  message(event) {
    console.log('hello')
  }
})

export const socket: Socket = {
  upgrade(req) {
    return app.handle(req)
  },
  message(peer, message) {
    listeners.forEach((listener) => listener.message(peer, message))
  },
};

This wrapper addresses the fact that Elysia does not have access to underlying WebSocket implementation when used within a framework like Next.js or SvelteKit. It's different when it's run as a standalone server using Bun's HTTP library.

@ledihildawan
Copy link

The first reason is that Elysia's WebSocket functionality only exists in the BunAdapter. You can tell because it has a ws method. When you integrate it with other frameworks, it switches to the web-standard adapter, which does not have a ws method. However, it has a websocket method and maybe it's a typo or unreleased feature.

A second thing to consider is whether Next.js even supports WebSockets. It would probably be helpful to review other people's attempts to use the feature in Next.js in the first place. For example, this blog with Socket.io.

Following up the second point, Elysia would need access to "server-upgrade" requests or equivalent in order to actually detect a WebSocket connection. Based on your framework, you may need to write a custom adapter. For example, based on the WebSocket implementation that SvelteKit is working on, an adapter might look roughly like this psuedo-code. I actually was able to get a rough proof of concept working, but it's definitely non-trivial.

// src/routes/ws/+server.ts

import type { Socket } from '@sveltejs/kit';

const listeners = new Set()

const app = new Elysia({
  adapter: {
    ...WebStandardAdapter,
   ws(app, path, options) {
    listeners.push({
     message: (peer, message) => {
      // handle data before invoking the original message callback, e.g. the one specified in the /ws call .
    }
    })
   }
  }
}).ws('/ws', {
  message(event) {
    console.log('hello')
  }
})

export const socket: Socket = {
  upgrade(req) {
    return app.handle(req)
  },
  message(peer, message) {
    listeners.forEach((listener) => listener.message(peer, message))
  },
};

This wrapper addresses the fact that Elysia does not have access to underlying WebSocket implementation when used within a framework like Next.js or SvelteKit. It's different when it's run as a standalone server using Bun's HTTP library.

I'll keep them separate for now; maybe if there's official documentation, I'll reconsider it later. Thank you for the feedback.

@ledihildawan
Copy link

The first reason is that Elysia's WebSocket functionality only exists in the BunAdapter. You can tell because it has a ws method. When you integrate it with other frameworks, it switches to the web-standard adapter, which does not have a ws method. However, it has a websocket method and maybe it's a typo or unreleased feature.

A second thing to consider is whether Next.js even supports WebSockets. It would probably be helpful to review other people's attempts to use the feature in Next.js in the first place. For example, this blog with Socket.io.

Following up the second point, Elysia would need access to "server-upgrade" requests or equivalent in order to actually detect a WebSocket connection. Based on your framework, you may need to write a custom adapter. For example, based on the WebSocket implementation that SvelteKit is working on, an adapter might look roughly like this psuedo-code. I actually was able to get a rough proof of concept working, but it's definitely non-trivial.

// src/routes/ws/+server.ts

import type { Socket } from '@sveltejs/kit';

const listeners = new Set()

const app = new Elysia({
adapter: {
...WebStandardAdapter,
ws(app, path, options) {
listeners.push({
message: (peer, message) => {
// handle data before invoking the original message callback, e.g. the one specified in the /ws call .
}
})
}
}
}).ws('/ws', {
message(event) {
console.log('hello')
}
})

export const socket: Socket = {
upgrade(req) {
return app.handle(req)
},
message(peer, message) {
listeners.forEach((listener) => listener.message(peer, message))
},
};
This wrapper addresses the fact that Elysia does not have access to underlying WebSocket implementation when used within a framework like Next.js or SvelteKit. It's different when it's run as a standalone server using Bun's HTTP library.

Yes, I just tried it, and the websocket successfully connected. We need to create a custom server first, and then follow the remaining steps as outlined in the previous instructions.

Next.js Documentation on Custom Server Setup

@Th4phat
Copy link
Author

Th4phat commented Apr 5, 2025

Thanks you guys for the solution.

@gopal-kamath
Copy link

@ap0nia I'm having similar issue but with NodeAdapter, the documentation says NodeAdapter has websocket support (https://elysiajs.com/blog/elysia-12.html#adapter) any idea how can I get that working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants