Documentation
¶
Overview ¶
Package websocketx 提供独立的标准 http.Handler WebSocket 传输,不依赖 Gin 或消息中间件。 它保持 Text/Binary 消息边界,提供认证、心跳、可选资格复核、有界队列及分阶段关闭。 身份、消息协议、用户/组索引与广播总线由上层业务决定。
基本用法 ¶
构造 Endpoint 后挂载普通 HTTP 路由;HTTP 服务和升级后的连接需要分别停止:
endpoint, err := websocketx.New(websocketx.Config{
MaxConnections: 1000,
OnMessage: func(ctx context.Context, session *websocketx.Session, message websocketx.Message) error {
// Text 和 Binary 均完整回送,不修改空白、换行或二进制字节。
return session.Send(ctx, message)
},
})
if err != nil {
return err
}
mux := http.NewServeMux()
mux.Handle("GET /ws", endpoint)
server := &http.Server{
Addr: ":8080",
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
}
// 应用自行启动 server.ListenAndServe 并接管信号;停机时共享同一个等待期限。
_ = endpoint.Stop()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
httpErr := server.Shutdown(ctx)
wsErr := endpoint.Wait(ctx)
if wsErr != nil {
endpoint.Cancel()
}
return errors.Join(httpErr, wsErr)
原始传输默认允许匿名,生产应用可配置 Authenticate 校验凭据并返回不可变 Identity。 AllowedOrigins 默认为完整 scheme/host/port 同源匹配;缺失 Origin 的非浏览器客户端默认允许。 HTTP 的 80、HTTPS 的 443 默认端口省略与显式填写等价;非默认端口仍须匹配。 代理后的外部 Origin 应显式配置,组件不信任 X-Forwarded-*。 RequireSubprotocol 要求至少一个配置子协议被客户端提供,握手失败不会执行业务消息回调。
与 ginx、httpserver 共用端口 ¶
三个包在应用层组合:ginx 负责路由,httpserver 负责唯一的端口监听,websocketx 管理升级后的连接。 下例的普通 HTTP 接口 http://localhost:8080/ping 与 WebSocket 地址 ws://localhost:8080/ws 共用端口。 代码放在返回 error 的函数中,需导入 context、errors、net/http、os、os/signal、syscall、time, 以及 github.com/gin-gonic/gin 和 github.com/bpcoder16/pixiu/infra 下的 ginx、httpserver、websocketx:
router, err := ginx.New(ginx.Config{})
if err != nil {
return err
}
endpoint, err := websocketx.New(websocketx.Config{
OnMessage: func(ctx context.Context, session *websocketx.Session, message websocketx.Message) error {
return session.Send(ctx, message)
},
})
if err != nil {
return err
}
router.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong")
})
router.GET("/ws", gin.WrapH(endpoint))
server, err := httpserver.New(httpserver.Config{
Addr: ":8080",
}, router)
if err != nil {
endpoint.Cancel()
return err
}
stop, release := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer release()
ran := make(chan error, 1)
go func() { ran <- server.Run() }()
var runErr error
select {
case runErr = <-ran:
case <-stop.Done():
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 先让两个组件开始停收和排空,再用同一个期限等待。
wsStopErr := endpoint.Stop()
httpStopErr := server.Stop()
httpWaitErr := server.Wait(ctx)
wsWaitErr := endpoint.Wait(ctx)
if httpWaitErr != nil {
server.Cancel()
}
if wsWaitErr != nil {
endpoint.Cancel()
}
return errors.Join(runErr, wsStopErr, httpStopErr, httpWaitErr, wsWaitErr)
HTTP 服务不负责回收已升级的 WebSocket 连接,因此两个组件需要分别 Stop/Wait,失败时分别 Cancel。
限额与所有权 ¶
默认握手期限 5 秒;认证同步执行,与升级共用期限。回调必须配合 ctx,不得异步保存请求对象。 Session.Context 不继承 HTTP 请求、HTTP Server 或应用信号的取消和可变日志作用域。 OnOpen、每次 OnMessage、Revalidate 均获得独立的日志/计时作用域;业务应使用回调 ctx 调用下游。 OnOpen 与 OnMessage 串行,Revalidate 可与消息处理并发,身份和业务共享状态必须并发安全。
默认收发单条上限各 1 MiB;接收 16 条/4 MiB、发送 64 条/4 MiB,包含在途操作。 默认共享 Budget 接收 128 MiB、发送 1 GiB;多个 Endpoint 只有显式注入同一个 Budget 才共享。 Budget.Usage 和 Session.Usage 是瞬时逻辑占用,包含读取中预留空间,不等于 RSS。 Budget.Limits 返回包含默认值的配置副本,供组合层判断过载恢复水位,不提供运行期改限额。 MaxPendingHandshakes 默认 256,MaxConnections 默认 10000;挂起回调和待收尾连接仍占名额。 默认连接上限按 Endpoint 分别计数,多入口部署须自行分配连接上限并按需共享 Budget。 1 GiB 发送预算可覆盖一轮 10000×64 KiB(625 MiB)逻辑积压;同时多轮仍可能超额。 单条 1 MiB 上限不代表能同时为全部连接积压 1 MiB,预算和连接数须按部署资源显式配置。 默认每 20 秒 Ping、60 秒 Pong 期限、10 秒写入期限、1 秒网络关闭期限。 OnCloseTimeout 默认 5 秒,从清理回调开始执行计时,不是网络关闭期限。 DisableHeartbeat 可显式禁用心跳。MessageTimeout 默认 30 秒,排队时间计入;复核默认每 60 秒执行,期限 5 秒。 数值负值非法;CompressionLevel 零值默认 1,可设置 1–9,压缩仅在 EnableCompression 时协商。
Send/SendPrepared 不等待网络或可用额度,成功只表示本地接纳。输入只在调用期间不可修改,返回后可复用。 SendWhileActive 还在接纳时检查额外的作用域 ctx,可用于限制请求回复的有效期。 Prepare 创建不可变帧;同 Endpoint 的多个连接可并发 SendPrepared,每连接仍扣完整逻辑字节预算。 ExpiresAt 为零时不过期;非零时接纳和实际写入前都检查。晚于入队的 ctx 取消不撤回消息。 ErrQueueFull 表示本连接满,ErrBudgetExceeded 表示共享预算满;组件不自动重试或把它们混为慢客户端。 OnMessage 的 Data 仅在回调期间只读有效,异步使用须自行复制并管理其工作生命周期。
消息大小与性能建议 ¶
以高频消息的条数吞吐、CPU 和尾延迟为优先时,建议单条完整消息控制在 1 KiB(1024 字节)以内。 大小按编码后、解压后的消息正文计算:不含 WebSocket 帧头,使用 realtime 时须包含 JSON 协议字段。 该建议来自 M4、Go 1.27.3、双进程各 GOMAXPROCS=4、32 连接、无 TLS/压缩的接收实验, 同时比较原始传输与 realtime + MemoryBus,并提高请求限流以测量饱和吞吐。 本轮 1 KiB 分别保留扫描最高条数吞吐的约 99.8% 和 90.3%;它不是所有业务的全局最优值。 较大消息按业务需要评估 CPU、P99 和积压内存;默认 ReadLimit/MaxSendBytes 仍各为 1 MiB, realtime 默认完整消息上限仍为 64 KiB。
停收与真实完成 ¶
StopInput 仅供上层组合:停止新握手、上行数据和新复核,保留已接纳业务和输出。 停收后通过底层读取器跳过未接纳正文,继续处理控制帧;不再解压、校验正文或检查解压后大小。 已开始的读取可继续到本次返回,发现停收后释放其预算并跳过剩余正文;底层帧解析和线上限额仍保留。 通常直接调用 Stop:先停止输入,等存量业务真正返回,再封闭发送、排空并关闭连接。 单独使用 StopInput 必须受有限的整体关闭期限约束:上层排空后调用 Stop/Wait,超时或失败时 Cancel。 与 apprun 一致,各阶段共用关闭期限;Endpoint 不另设停收定时器,也不保证每个阶段都能在 Cancel 前完成。 Wait 只等待真实收尾,超时不取消业务;调用方需要显式 Cancel。 Cancel 不等待网络、业务或观察器;忽略取消的回调继续占用资源,Done 只在其实际返回后关闭。 收尾期间的已知过期、丢弃、写入和回调失败通过 DrainError 汇总;历史失败不污染当前关闭结果。
Session.Close 发起单连接关闭并丢弃未写消息。Detached 表示连接已经不可路由,Done 表示全部收尾完成。 OnDetach 在内部锁外同步执行,只能做快速内存索引清理;它可早于 OnOpen 返回。 网络回收不等待用户钩子,OnClose 等在途业务、读写和复核真实结束后运行一次。 OnClose 的 ctx 不继承会话断连取消;普通断连、Stop 和 Wait 超时不取消清理,Endpoint.Cancel 会取消它。 清理须使用回调 ctx 并配合 OnCloseTimeout/Cancel,实际返回前 Done 不关闭;停收期间清理失败计入 DrainError。 所有回调都不能同步 Wait 自身或所属 Endpoint;Observe 应快速、并发安全,不能代替持久化业务审计。 组件日志/观察仅含元信息,回调错误和 panic 值不会原样进入组件日志。 关闭观察区分正常停机、传输断开、读取超时及协议错误;1006 仅作本地异常断开状态,不发送到网络。 回调自身超时保留 context.DeadlineExceeded,先发生的主动取消保留 context.Canceled。 1000 正常关闭后按时返回 nil 的回调仍算成功;Endpoint.Cancel、关闭故障及实际队列丢弃仍按失败处理。
HTTP Shutdown 不回收已 Hijack 的连接。应用应先完成服务 Stop/Wait 或超时 Cancel, 然后按既有资源栈顺序回收共享客户端,最后关闭日志;不要在资源阶段再次无限等待 Endpoint。
Index ¶
- Variables
- type Budget
- type BudgetConfig
- type Config
- type DrainError
- type Endpoint
- func (e *Endpoint) Budget() *Budget
- func (e *Endpoint) Cancel()
- func (e *Endpoint) Done() <-chan struct{}
- func (e *Endpoint) Get(id string) (*Session, bool)
- func (e *Endpoint) Len() int
- func (e *Endpoint) Prepare(message Message) (*PreparedMessage, error)
- func (e *Endpoint) Range(fn func(*Session) bool)
- func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (e *Endpoint) Stop() error
- func (e *Endpoint) StopInput() error
- func (e *Endpoint) Wait(ctx context.Context) error
- type Event
- type EventKind
- type Identity
- type Message
- type MessageType
- type PreparedMessage
- type Session
- func (s *Session) Close(code int, reason string) (bool, error)
- func (s *Session) Context() context.Context
- func (s *Session) Detached() <-chan struct{}
- func (s *Session) Done() <-chan struct{}
- func (s *Session) ID() string
- func (s *Session) Identity() Identity
- func (s *Session) RemoteAddr() string
- func (s *Session) Send(ctx context.Context, message Message) error
- func (s *Session) SendPrepared(ctx context.Context, message *PreparedMessage) error
- func (s *Session) SendWhileActive(ctx, activeCtx context.Context, message Message) error
- func (s *Session) Subprotocol() string
- func (s *Session) Usage() Usage
- type Usage
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrClosed 表示连接或 Endpoint 已关闭或当前不接纳该操作。 ErrClosed = errors.New("websocketx: closed") // ErrNilContext 表示调用方传入了 nil context。 ErrNilContext = errors.New("websocketx: nil context") // ErrQueueFull 表示单连接队列额度或 Endpoint 接纳名额不足。 ErrQueueFull = errors.New("websocketx: connection queue full") // ErrBudgetExceeded 表示共享收发预算不足。 ErrBudgetExceeded = errors.New("websocketx: shared budget exceeded") // ErrMessageTooLarge 表示单条消息超过配置的字节上限。 ErrMessageTooLarge = errors.New("websocketx: message too large") // ErrInvalidMessage 表示消息或握手校验失败。 ErrInvalidMessage = errors.New("websocketx: invalid message") // ErrWrongEndpoint 表示预制消息未初始化或属于其他 Endpoint。 ErrWrongEndpoint = errors.New("websocketx: prepared message belongs to another endpoint") // ErrExpired 表示消息已过业务有效期或排队处理期限。 ErrExpired = errors.New("websocketx: expired") // ErrCallback 表示回调失败,用于隐藏原始错误详情。 ErrCallback = errors.New("websocketx: callback failed") // ErrPanic 表示组件捕获到回调 panic。 ErrPanic = errors.New("websocketx: callback panic") // ErrDrainFailed 表示停收后的排空或收尾存在失败,详情见 DrainError。 ErrDrainFailed = errors.New("websocketx: drain lost work or cleanup failed") )
Functions ¶
This section is empty.
Types ¶
type Budget ¶
type Budget struct {
// contains filtered or unexported fields
}
Budget 并发安全,零值使用默认配置;首次使用后不得复制。
func NewBudget ¶
func NewBudget(cfg BudgetConfig) (*Budget, error)
func (*Budget) Limits ¶
func (b *Budget) Limits() BudgetConfig
Limits 返回包含默认值的只读配置副本,供组合层判断过载恢复水位。 条数为零表示不限制;修改返回值不会影响正在使用的预算。
type BudgetConfig ¶
type BudgetConfig struct {
ReceiveBytes int64
SendBytes int64
ReceiveMessages int64
SendMessages int64
}
BudgetConfig 设置多个 Endpoint 共用的逻辑积压上限。 字节零值默认接收 128 MiB、发送 1 GiB;条数零值不设共享条数上限。
type Config ¶
type Config struct {
// HandshakeTimeout 是认证与升级共用的期限,默认 5 秒。
HandshakeTimeout time.Duration
// ReadLimit 限制正常接收时客户端 → 服务端的单条消息字节数(含解压后),默认 1 MiB。
// 停收后跳过未接纳正文的解压和大小校验,仍保留底层线上限额。
ReadLimit int64
// MaxSendBytes 限制服务端 → 客户端的单条消息正文字节数(按压缩前计算),默认 1 MiB。
MaxSendBytes int64
// ReceiveQueueSize 是单连接客户端 → 服务端的累计消息条数上限,默认 16。
// 包含正在读取组装、排队等待处理和正在派发处理的消息。
ReceiveQueueSize int
// ReceiveQueueBytes 是单连接客户端 → 服务端的累计正文字节数上限,默认 4 MiB。
// 包含读取组装中、排队等待处理和正在派发处理的正文,按解压后字节数计算。
ReceiveQueueBytes int64
// SendQueueSize 是单连接服务端 → 客户端的累计消息条数上限,默认 64。
// 包含排队等待发送和正在写入网络的消息。
SendQueueSize int
// SendQueueBytes 是单连接服务端 → 客户端的累计正文字节数上限,默认 4 MiB。
// 包含排队等待发送和正在写入网络的正文,按压缩前字节数计算。
SendQueueBytes int64
// Budget 可供多个 Endpoint 共享;nil 时创建独立的默认预算。
Budget *Budget
// MaxPendingHandshakes 是在途握手上限,默认 256。
MaxPendingHandshakes int
// MaxConnections 是连接总数上限(含握手和收尾),默认 10000。
MaxConnections int
// PingInterval 是主动 Ping 间隔,默认 20 秒,启用心跳时须小于 PongTimeout。
PingInterval time.Duration
// PongTimeout 是接收 Pong 的期限,默认 60 秒,每次收到 Pong 后重置。
PongTimeout time.Duration
// DisableHeartbeat 默认为 false,即开启心跳。
// 设为 true 后不主动发送 Ping、不检查 Pong 超时,但仍会回复客户端的 Ping。
DisableHeartbeat bool
// WriteTimeout 是出站网络写入期限,默认 10 秒,适用于单条数据消息和主动 Ping。
// 从实际开始写入时计时,不包含发送队列等待时间;超时或写入失败时发起关闭连接。
WriteTimeout time.Duration
// CloseTimeout 是发起连接关闭后发送 Close 控制帧(关闭通知)的期限,默认 1 秒。
// 通知发送完成、超时或失败后均关闭底层连接;仅控制通知发送,不是整个关闭流程的超时。
CloseTimeout time.Duration
// OnCloseTimeout 是 OnClose 清理 context 的期限,默认 5 秒,从回调开始执行计时。
// 清理不继承会话断连取消,但响应 Endpoint.Cancel;回调须配合取消,实际返回前不关闭 Done。
OnCloseTimeout time.Duration
// MessageTimeout 是 OnOpen 初始化和入站消息业务处理的期限,默认 30 秒,不是网络读取超时。
// OnOpen 从开始执行计时;消息从完整接纳至 OnMessage 返回计时,包含接收队列等待时间。
// 消息过期或回调超时会发起关闭连接;正在执行的回调须响应 ctx 取消,不能被强制终止。
MessageTimeout time.Duration
// RevalidateInterval 是资格复核的基准间隔,默认 60 秒。
RevalidateInterval time.Duration
// RevalidateTimeout 是单次资格复核期限,默认 5 秒。
RevalidateTimeout time.Duration
// AllowedOrigins 是允许的完整 Origin 列表,空列表默认按 scheme/host/port 校验同源。
// HTTP 的 80、HTTPS 的 443 默认端口可省略,非默认端口须匹配。
AllowedOrigins []string
// AllowAnyOrigin 允许任意合法 Origin,与非空 AllowedOrigins 互斥。
AllowAnyOrigin bool
// RejectMissingOrigin 为 true 时拒绝缺失 Origin 的请求,默认允许。
RejectMissingOrigin bool
// Subprotocols 是服务端支持的子协议候选列表,按优先级从高到低排列;客户端也可提供多个候选。
// 按服务端列表顺序选择第一个双方都支持的子协议,匹配成功时仅选定一个,由 Session.Subprotocol() 返回。
// 无匹配时的服务端行为由 RequireSubprotocol 决定。
Subprotocols []string
// RequireSubprotocol 默认为 false,控制服务端是否强制要求协商出子协议。
// 为 true 时 Subprotocols 不得为空;客户端未提供候选或无匹配时,在升级前返回 HTTP 400。
// 为 false 时,无匹配不阻止服务端升级,响应不携带 Sec-WebSocket-Protocol,Session.Subprotocol() 返回空字符串。
RequireSubprotocol bool
// EnableCompression 为 true 时协商消息压缩,默认关闭。
EnableCompression bool
// CompressionLevel 为零时默认 flate.BestSpeed;仅影响启用压缩的连接。
CompressionLevel int
// CheckReady 是可选的快速只读接纳门,在锁外调用;false 返回 HTTP 503。
CheckReady func() bool
// Authenticate 在握手时认证并生成身份;nil 时允许匿名连接。
Authenticate func(context.Context, *http.Request) (Identity, error)
// OnOpen 在认证和 WebSocket 升级成功后、该连接的消息派发前执行。
// 与 OnMessage 同连接串行;返回错误时关闭连接,不再派发该连接的消息。
// 单连接回调时序(省略未配置的回调):
//
// Authenticate -> 升级成功 -> OnOpen -> OnMessage -> OnMessage -> ...
// (同连接串行,Revalidate 可与业务回调并发)
//
// 连接建立后的任意阶段触发关闭(可能仍在执行 OnOpen/OnMessage)
// -> 标记关闭、摘除活跃索引、取消 Session.Context、关闭 Detached
// +-> OnDetach -------------------------------------------+
// +-> 关闭网络,等待在途业务、读写和复核结束 -------------+-> OnClose -> 收尾 -> Done
//
// 网络回收与 OnDetach 独立推进;两条关闭分支实际结束后才执行 OnClose。
// 收尾包含关闭观察和释放连接名额,完成后才关闭 Session.Done()。
// 提前关闭时 OnOpen/OnMessage 可能不执行;握手失败不会进入这些连接回调。
OnOpen func(context.Context, *Session) error
// OnMessage 在 OnOpen 成功返回后按连接串行处理完整消息;nil 时丢弃消息。
OnMessage func(context.Context, *Session, Message) error
// OnDetach 在连接首次关闭、摘除活跃索引并取消 Session.Context 后调用一次。
// 此时 Detached 已关闭,但网络和在途 OnOpen/OnMessage/Revalidate 可能尚未结束。
// 在传输内部锁外同步执行,只做快速内存索引清理,不执行 I/O;
// 不得在此释放仍被在途回调使用的业务资源,也不得同步等待自身或所属 Endpoint 完成。
OnDetach func(*Session)
// OnClose 等网络、在途业务、读写、复核和 OnDetach 全部结束后执行一次。
// 可在此释放会话业务资源并执行清理 I/O;须使用回调 ctx,不使用已取消的 Session.Context。
// ctx 独立于会话断连取消,受 OnCloseTimeout(默认 5 秒)及 Endpoint.Cancel 约束。
// 超时或取消不能强制终止回调,实际返回前 Session.Done 不关闭。
OnClose func(context.Context, *Session)
// Revalidate 可与消息处理并发,返回错误时关闭连接;nil 时不启用复核。
Revalidate func(context.Context, *Session) error
// Observe 同步、并发安全且应快速返回;事件不携带正文或凭据。
Observe func(context.Context, Event)
// Logger 为 nil 时使用 logit.Default,组件不拥有或关闭 Logger。
Logger logit.Logger
}
Config 配置原始传输,数值零值采用默认值。 回调不能同步等待自身或所属 Endpoint 完成;业务自行等待派生的后台工作。
type DrainError ¶
type DrainError struct {
ReceiveDropped uint64
ReceiveExpired uint64
SendDropped uint64
SendExpired uint64
WriteErrors uint64
// CallbackErrors 统计停收期间传输层回调的失败次数,同一连接可计多次。
// 上层适配回调收到取消也可能计数,即使它没有调用业务 OnClose。
CallbackErrors uint64
}
DrainError 汇总首次 StopInput 后的已知失败,不保留正文或无界错误列表。 计数可能覆盖同一消息的不同阶段,不能直接相加作为唯一丢失消息数。
func (*DrainError) Error ¶
func (e *DrainError) Error() string
func (*DrainError) Unwrap ¶
func (e *DrainError) Unwrap() error
type Endpoint ¶
type Endpoint struct {
// contains filtered or unexported fields
}
Endpoint 是 WebSocket 服务入口,负责握手、会话管理和关闭收尾。 实现 http.Handler,使用 New 构造;不监听端口,也不关闭应用借用的资源。
func New ¶
Example ¶
package main
import (
"context"
"fmt"
"net/http/httptest"
"strings"
"time"
"github.com/bpcoder16/pixiu/infra/websocketx"
"github.com/gorilla/websocket"
)
func main() {
endpoint, err := websocketx.New(websocketx.Config{
MaxConnections: 100,
OnMessage: func(ctx context.Context, session *websocketx.Session, message websocketx.Message) error {
return session.Send(ctx, message)
},
})
if err != nil {
panic(err)
}
server := httptest.NewServer(endpoint)
defer server.Close()
client, _, err := websocket.DefaultDialer.Dial("ws"+strings.TrimPrefix(server.URL, "http"), nil)
if err != nil {
panic(err)
}
defer client.Close()
if err := client.WriteMessage(websocket.TextMessage, []byte("hello\nworld")); err != nil {
panic(err)
}
_, text, err := client.ReadMessage()
if err != nil {
panic(err)
}
fmt.Printf("%q\n", text)
if err := client.WriteMessage(websocket.BinaryMessage, []byte{0, 255}); err != nil {
panic(err)
}
_, binary, err := client.ReadMessage()
if err != nil {
panic(err)
}
fmt.Println(binary)
_ = endpoint.Stop()
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := endpoint.Wait(ctx); err != nil {
endpoint.Cancel()
panic(err)
}
}
Output: "hello\nworld" [0 255]
func (*Endpoint) Prepare ¶
func (e *Endpoint) Prepare(message Message) (*PreparedMessage, error)
Prepare 复制一份正文并由 Gorilla 缓存固定编码选项对应的帧;不占发送队列预算。
func (*Endpoint) ServeHTTP ¶
func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP 的握手同步执行,返回后不再保存或使用 HTTP/Gin 请求对象。
type Event ¶
type Event struct {
Kind EventKind
ConnectionID string
Type MessageType
Bytes int64
Duration time.Duration
Code int
Err error
Usage Usage
}
Event 仅包含元信息;Err 为脱敏的分类错误,不含用户错误文本或 panic 值。 EventClosed 的 Code 可包含仅供本地观察的 1006,Err 可包含读取失败、回调超时及收尾钩子的故障分类。
type EventKind ¶
type EventKind string
EventKind 标识不包含业务正文的传输事件。
const ( EventHandshake EventKind = "handshake" EventOpened EventKind = "opened" EventReceived EventKind = "received" EventHandled EventKind = "handled" EventSent EventKind = "sent" EventSendDropped EventKind = "send_dropped" EventReceiveDropped EventKind = "receive_dropped" EventRevalidated EventKind = "revalidated" EventClosed EventKind = "closed" )
type Message ¶
type Message struct {
Type MessageType
Data []byte
ExpiresAt time.Time
}
Message 的 Data 在 OnMessage 期间只读有效;Send 返回后调用方可复用输入。 ExpiresAt 为零表示不过期,入站消息不附加业务有效期。
type MessageType ¶
type MessageType int
MessageType 只支持完整的 Text 或 Binary 数据消息,控制帧由组件管理。
const ( Text MessageType = 1 Binary MessageType = 2 )
type PreparedMessage ¶
type PreparedMessage struct {
// contains filtered or unexported fields
}
PreparedMessage 绑定 Endpoint 和不可变帧,业务不得复用到其他 Endpoint。
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session 由 Endpoint 管理;发送并发安全,身份与连接属性创建后不变。
func (*Session) RemoteAddr ¶
func (*Session) SendPrepared ¶
func (s *Session) SendPrepared(ctx context.Context, message *PreparedMessage) error
func (*Session) SendWhileActive ¶
SendWhileActive 与 Send 共用队列;额外的 activeCtx 非 nil 时也必须在接纳时有效。 入队后任一 context 取消都不会撤回消息。