Zum Inhalt springen

WebSocket-Helfer ​

Der WebSocket-Helfer unterstützt serverseitige WebSockets in Hono-Anwendungen. Derzeit sind Adapter für Cloudflare Workers / Pages, Deno, Bun und Node.js verfügbar.

Import ​

Der Adapter für jede Laufzeitumgebung ist ein separates Paket (@hono/cloudflare-workers, @hono/deno, @hono/bun, ...). Installiere das Paket für deine Laufzeitumgebung.

ts
import { Hono } from 'hono'
import { upgradeWebSocket } from '@hono/cloudflare-workers'
ts
import { Hono } from 'hono'
import { upgradeWebSocket } from '@hono/deno'
ts
import { Hono } from 'hono'
import { upgradeWebSocket, websocket } from '@hono/bun'

// ...

export default {
  fetch: app.fetch,
  websocket,
}
ts
import { serve, upgradeWebSocket } from '@hono/node-server'
import { Hono } from 'hono'
import { WebSocketServer } from 'ws'

Unter Node.js ist die WebSocket-Unterstützung in @hono/node-server integriert. Installiere zum Aktivieren ws und bei Verwendung von TypeScript zusätzlich @types/ws. Erstelle anschließend einen WebSocketServer mit { noServer: true } und übergib ihn über die Option websocket an serve().

@hono/node-ws ist veraltet.

upgradeWebSocket() ​

upgradeWebSocket() gibt einen Handler zur Verarbeitung von WebSockets zurück.

ts
const app = new Hono()

app.get(
  '/ws',
  upgradeWebSocket((c) => {
    return {
      onMessage(event, ws) {
        console.log(`Message from client: ${event.data}`)
        ws.send('Hello from server!')
      },
      onClose: () => {
        console.log('Connection closed')
      },
    }
  })
)

Verfügbare Ereignisse:

  • onOpen - Wird derzeit von Cloudflare Workers nicht unterstützt.
  • onMessage
  • onClose
  • onError

Achtung

Wenn du auf einer Route mit dem WebSocket-Helfer Middleware verwendest, die Header verändert, etwa CORS-Middleware, kann ein Fehler auftreten, dass unveränderliche Header nicht geändert werden dürfen. Das liegt daran, dass auch upgradeWebSocket() intern Header verändert.

Sei daher vorsichtig, wenn du den WebSocket-Helfer und Middleware gleichzeitig verwendest.

RPC-Modus ​

Mit dem WebSocket-Helfer definierte Handler unterstützen den RPC-Modus.

ts
// server.ts
const wsApp = app.get(
  '/ws',
  upgradeWebSocket((c) => {
    //...
  })
)

export type WebSocketApp = typeof wsApp

// client.ts
const client = hc<WebSocketApp>('http://localhost:8787')
const socket = client.ws.$ws() // A WebSocket object for a client

Beispiele ​

Sieh dir die Beispiele mit dem WebSocket-Helfer an.

Server und Client ​

ts
// server.ts
import { Hono } from 'hono'
import { upgradeWebSocket } from '@hono/cloudflare-workers'

const app = new Hono().get(
  '/ws',
  upgradeWebSocket(() => {
    return {
      onMessage: (event) => {
        console.log(event.data)
      },
    }
  })
)

export default app
ts
// client.ts
import { hc } from 'hono/client'
import type app from './server'

const client = hc<typeof app>('http://localhost:8787')
const ws = client.ws.$ws(0)

ws.addEventListener('open', () => {
  setInterval(() => {
    ws.send(new Date().toString())
  }, 1000)
})

Bun mit JSX ​

tsx
import { Hono } from 'hono'
import { upgradeWebSocket, websocket } from '@hono/bun'
import { html } from 'hono/html'

const app = new Hono()

app.get('/', (c) => {
  return c.html(
    <html>
      <head>
        <meta charset='UTF-8' />
      </head>
      <body>
        <div id='now-time'></div>
        {html`
          <script>
            const ws = new WebSocket('ws://localhost:3000/ws')
            const $nowTime = document.getElementById('now-time')
            ws.onmessage = (event) => {
              $nowTime.textContent = event.data
            }
          </script>
        `}
      </body>
    </html>
  )
})

const ws = app.get(
  '/ws',
  upgradeWebSocket((c) => {
    let intervalId
    return {
      onOpen(_event, ws) {
        intervalId = setInterval(() => {
          ws.send(new Date().toString())
        }, 200)
      },
      onClose() {
        clearInterval(intervalId)
      },
    }
  })
)

export default {
  fetch: app.fetch,
  websocket,
}

Node.js ​

ts
import { serve, upgradeWebSocket } from '@hono/node-server'
import { Hono } from 'hono'
import { WebSocketServer } from 'ws'

const app = new Hono()

app.get(
  '/ws',
  upgradeWebSocket(() => ({
    onMessage(event, ws) {
      ws.send(event.data)
    },
  }))
)

const wss = new WebSocketServer({ noServer: true })

serve({
  fetch: app.fetch,
  websocket: { server: wss },
})

Veröffentlicht unter der MIT-Lizenz.