H
Hono•3w ago
Kazz

Node Web Sockets in Hono

Hello all, I'm fairly new to Hono and I've recently picked it up for some of my projects and enjoyed it very much. Im currently facing problems with one of my projects that uses WebSockets to communicate with Hardware boxes. And I will need another WebSocket as well to communicate with my frontend and mobile application. I've searched for many solutions online but it looks like Hono with Node WebSockets is rarely talked about. After a lot of trial and error I finally reached this code to let my socket run with Hono [1/3]
26 Replies
Kazz
KazzOP•3w ago
const httpServer = createServer(async (req, res) => {
try {
// Handle WebSocket upgrade requests separately
if (req.headers.upgrade && req.headers.upgrade.toLowerCase() === 'websocket') return

// Convert Node.js request to Web standard Request
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`)
const headers = new Headers()
Object.entries(req.headers).forEach(([key, value]) => {
if (value) headers.set(key, Array.isArray(value) ? value.join(', ') : value)
})

const body = req.method !== 'GET' && req.method !== 'HEAD' ? req : null
// Create readable stream from request body
let bodyStream = null
if (body) {
bodyStream = new ReadableStream({
start(controller) {
body.on('data', chunk => controller.enqueue(chunk))
body.on('message', chunk => controller.enqueue(chunk))
body.on('end', () => controller.close())
body.on('error', err => controller.error(err))
},
})
}

const request = new Request(url.toString(), { method: req.method, headers, body: bodyStream })

const response = await app.fetch(request)

// Write the response back to the Node.js response object
res.writeHead(response.status, Object.fromEntries(response.headers.entries()))

const responseBody = await response.arrayBuffer()
res.end(Buffer.from(responseBody))
} catch (err) {
console.error('Error handling request:', err)
res.writeHead(500)
res.end('Internal Server Error')
}
})
const wss = new WebSocketServer({ server: httpServer, path: '/ws' })

serve({ fetch:app.fetch, port:config.PORT, createServer:()=>httpServer }, info => console.log(`šŸ’Ø API server is running on Port ${info.port}`))
const httpServer = createServer(async (req, res) => {
try {
// Handle WebSocket upgrade requests separately
if (req.headers.upgrade && req.headers.upgrade.toLowerCase() === 'websocket') return

// Convert Node.js request to Web standard Request
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`)
const headers = new Headers()
Object.entries(req.headers).forEach(([key, value]) => {
if (value) headers.set(key, Array.isArray(value) ? value.join(', ') : value)
})

const body = req.method !== 'GET' && req.method !== 'HEAD' ? req : null
// Create readable stream from request body
let bodyStream = null
if (body) {
bodyStream = new ReadableStream({
start(controller) {
body.on('data', chunk => controller.enqueue(chunk))
body.on('message', chunk => controller.enqueue(chunk))
body.on('end', () => controller.close())
body.on('error', err => controller.error(err))
},
})
}

const request = new Request(url.toString(), { method: req.method, headers, body: bodyStream })

const response = await app.fetch(request)

// Write the response back to the Node.js response object
res.writeHead(response.status, Object.fromEntries(response.headers.entries()))

const responseBody = await response.arrayBuffer()
res.end(Buffer.from(responseBody))
} catch (err) {
console.error('Error handling request:', err)
res.writeHead(500)
res.end('Internal Server Error')
}
})
const wss = new WebSocketServer({ server: httpServer, path: '/ws' })

serve({ fetch:app.fetch, port:config.PORT, createServer:()=>httpServer }, info => console.log(`šŸ’Ø API server is running on Port ${info.port}`))
[2/3] However this doesn't look like good code at all and I was expecting it to give me errors in the future. Which it did. I used Better-Auth with Hono and here is were my problems started showing. A lot of better auth functionalities got limited and some break because of this code. And I'm pretty sure later on other things will break because of this [3/3] Is there a better way to allow Web socket to run with Hono without creating a server?
Arjix
Arjix•3w ago
I like the fake parts, [1/?]
Kazz
KazzOP•3w ago
Lol i had no idea how many posts i will do xD
Arjix
Arjix•3w ago
I am pretty sure the docs show exactly that? all parts are part = 1 that's what I meant
Kazz
KazzOP•3w ago
I looked for it, they only show for Deno and Bun and Cloudflare workers https://hono.dev/docs/helpers/websocket
WebSocket Helper - Hono
Web framework built on Web Standards for Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Node.js, and others. Fast, but not only fast.
Arjix
Arjix•3w ago
No description
Kazz
KazzOP•3w ago
Im blind
Arjix
Arjix•3w ago
we all are props to you for pushing through with that hacky way though! not giving up is an important skill but carefully reading the docs is another important skill
atoko
atoko•3w ago
ā€˜ import { Hono } from 'hono'; import { ws } from 'hono/ws'; const app = new Hono(); // Define a WebSocket route app.get( '/ws', ws((ws) => { console.log('WebSocket connection established.'); // Handle incoming messages ws.onmessage = (event) => { console.log('Received:', event.data); ws.send(Echo: ${event.data}); }; // Handle connection close ws.onclose = () => { console.log('WebSocket connection closed.'); }; }) ); // Start the app app.fire(); ā€˜
Arjix
Arjix•3w ago
yeah I am sure they can read the docs, no need for snippets
atoko
atoko•3w ago
I was wondering about that lol, here is an example by chatgpt
Kazz
KazzOP•3w ago
Thanks! Now I have to go rewrite most of my code šŸ‘ I'll mark this as solved for now
Arjix
Arjix•3w ago
well, I hope it is a rewarding experience
atoko
atoko•3w ago
The funny part is I went to GPT4o to ask for a hono node ws and it came up with something similar to OP I had to also remind it of the middleware to get the above
Arjix
Arjix•3w ago
is GPT4 actually using the LLM.txt provided by the docs?
atoko
atoko•3w ago
So dont feel bad even AI isnt aware lol
Arjix
Arjix•3w ago
if so, sweet
Kazz
KazzOP•3w ago
Rewarding is one word for it
atoko
atoko•3w ago
Not sure
Kazz
KazzOP•3w ago
I dont think so, i rarely use GPT4 But AI's in general are not up to date with the latest Hono tech thats for sure
Arjix
Arjix•3w ago
maybe you can directly tell it to search through the LLM.txt? e.g.
how to do xyz in hono?

please first search through the docs before giving an answer
https://hono.dev/llms.txt
how to do xyz in hono?

please first search through the docs before giving an answer
https://hono.dev/llms.txt
it actually worked
Kazz
KazzOP•3w ago
Interesting thet GPT could do it and not Claude
Arjix
Arjix•3w ago
I did have "Search" enabled as a tool does claude have smth similar? as an alternative, you can provide https://hono.dev/llms-full.txt as a resource instead iirc they call it "embedding" or smth
Kazz
KazzOP•3w ago
RIP my wallet. But yeah i guess Claude cant do this now, or at least on the free version. GPT did it without the "serach" enabled though it wasnt as accurate as the answer you got
Arjix
Arjix•3w ago
I can't get good results in https://duck.ai I guess it doesn't enable tools like "Search"
DuckDuckGo AI Chat at DuckDuckGo
DuckDuckGo. Privacy, Simplified.

Did you find this page helpful?