RRuna

WebSocket

Hub 与广播

ws 提供 WebSocket Hub、频道订阅、事件处理和广播。它挂载在 route 上,因此需要同时安装 route

WebSocket 适合聊天、通知、实时进度、控制台监控这类服务端主动推送场景。普通请求响应接口不要为了“实时感”强行使用 WebSocket。

安装

go get github.com/duxweb/runa/ws github.com/duxweb/runa/route

Redis 横向扩展按需安装:

go get github.com/duxweb/runa/ws/redis

创建 Hub

hub := ws.New("default", ws.Config{
    Origin: []string{"http://localhost:3000"},
})

hub.On("chat.message", func(ctx *ws.Context) error {
    return ctx.Publish("room", "chat.message", ctx.Message().Data)
})

接入应用

package main

import (
    "context"

    "github.com/duxweb/runa"
    "github.com/duxweb/runa/route"
    "github.com/duxweb/runa/ws"
)

func main() {
    hub := ws.New("default", ws.Config{})
    hub.On("echo", func(ctx *ws.Context) error {
        return ctx.Reply(runa.Map{"data": ctx.Message().Data})
    })

    app := runa.New()
    app.Install(route.Provider(route.Addr(":8080")), ws.Provider(hub))

    route.Default().Get("/ws", hub.Serve).SkipDoc()

    if err := app.Run(context.Background()); err != nil {
        panic(err)
    }
}

ws.Mount(target, hub) 会在传入目标的 / 路径挂载 Hub。如果希望最终地址是 /ws,可以这样写:

ws.Mount(route.Default().Group("/ws"), hub)

配置

ws.Config 通过代码传入,也可以由 ws.Provider 合并读取对应 Hub 配置。

常用字段:

字段 说明
Origin 允许的 Origin 列表
MaxMessageSize 最大消息体
ReadTimeout 读取超时
WriteTimeout 写入超时
PingInterval ping 间隔
PongTimeout pong 超时
SendBuffer 发送缓冲
Auth 连接认证回调
Broker 跨节点广播
Presence 在线状态存储

频道和事件怎么理解

  • channel 是消息房间,比如 room:1user:1
  • event 是消息类型,比如 chat.messagenotify.created
  • client 订阅 channel 后,可以收到该 channel 上发布的事件

Redis 横向扩展

import wsredis "github.com/duxweb/runa/ws/redis"

hub := ws.New("default", ws.Config{
    Broker: wsredis.Broker(client, "ws"),
    Presence: wsredis.Presence(client, "runa:ws:"),
})

客户端消息格式

{"id":"1","event":"subscribe","channel":"room"}
{"id":"2","event":"echo","data":{"text":"hello"}}

内置事件包括 subscribeunsubscribeping

命令

安装 ws.Provider(...) 后会注册:

go run . ws:list
go run . ws:channels default
go run . ws:stats default
go run . ws:kick default <client-id>

常见错误

直接 ws.Mount 后路径不是预期

ws.Mount(target, hub) 会挂到 target 的 /。如果最终路径要 /ws,传 route.Default().Group("/ws")

生产环境没有限制 Origin

浏览器 WebSocket 应限制允许的 Origin,避免被其他站点滥用。

多实例广播只用内存

默认只能在当前进程内广播。多实例部署要接入 Redis Broker 和 Presence。

API 速查

  • ws.New(name, config) 创建 Hub
  • ws.Provider(hubs...) 接入框架生命周期
  • ws.Mount(target, hub)target/ 路径挂载 Hub
  • hub.On(event, handler) 注册事件处理器
  • hub.Publish(channel, event, data) 向频道发布消息
  • hub.Broadcast(event, data) 向所有客户端广播消息
  • ws/redis.Brokerws/redis.Presence 提供跨节点能力
编辑此页