Appearance
WebSocket 助手
¥WebSocket Helper
WebSocket Helper 是 Hono 应用中服务器端 WebSockets 的助手。目前 Cloudflare Workers / Pages、Deno 和 Bun 适配器可用。
¥WebSocket Helper is a helper for server-side WebSockets in Hono applications. Currently Cloudflare Workers / Pages, Deno, and Bun adapters are available.
导入
¥Import
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 { createBunWebSocket } from 'hono/bun'
import type { ServerWebSocket } from 'bun'
const { upgradeWebSocket, websocket } =
createBunWebSocket<ServerWebSocket>()
// ...
export default {
fetch: app.fetch,
websocket,
}
如果你使用 Node.js,则可以使用 @hono/node-ws。
¥If you use Node.js, you can use @hono/node-ws.
upgradeWebSocket()
upgradeWebSocket()
返回用于处理 WebSocket 的处理程序。
¥upgradeWebSocket()
returns a handler for handling WebSocket.
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')
},
}
})
)
可用事件:
¥Available events:
onOpen
- 目前,Cloudflare Workers 不支持它。¥
onOpen
- Currently, Cloudflare Workers does not support it.onMessage
onClose
onError
警告
如果你在使用 WebSocket Helper 的路由上使用修改标头的中间件(例如,应用 CORS),则可能会遇到错误,提示你无法修改不可变标头。这是因为 upgradeWebSocket()
也在内部更改标头。
¥If you use middleware that modifies headers (e.g., applying CORS) on a route that uses WebSocket Helper, you may encounter an error saying you can't modify immutable headers. This is because upgradeWebSocket()
also changes headers internally.
因此,如果你同时使用 WebSocket Helper 和中间件,请谨慎使用。
¥Therefore, please be cautious if you are using WebSocket Helper and middleware at the same time.
RPC 模式
¥RPC-mode
使用 WebSocket Helper 定义的处理程序支持 RPC 模式。
¥Handlers defined with WebSocket Helper support RPC mode.
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
示例
¥Examples
查看使用 WebSocket Helper 的示例。
¥See the examples using WebSocket Helper.
服务器和客户端
¥Server and 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)
})
带有 JSX 的 Bun
¥Bun with JSX
tsx
import { Hono } from 'hono'
import { createBunWebSocket } from 'hono/bun'
const { upgradeWebSocket, websocket } = createBunWebSocket()
const app = new Hono()
app.get('/', (c) => {
return c.html(
<html>
<head>
<meta charset='UTF-8' />
</head>
<body>
<div id='now-time'></div>
<script
dangerouslySetInnerHTML={{
__html: `
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,
}