Help us shape the future of Go! Take the 2026 Go Developer Survey

websocketx

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

View Source
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 返回包含默认值的只读配置副本,供组合层判断过载恢复水位。 条数为零表示不限制;修改返回值不会影响正在使用的预算。

func (*Budget) Usage

func (b *Budget) Usage() Usage

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

func New(cfg Config) (*Endpoint, error)
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) Budget

func (e *Endpoint) Budget() *Budget

func (*Endpoint) Cancel

func (e *Endpoint) Cancel()

Cancel 同步封闭输出、通知取消,网络和回调收尾由已有工作负责。

func (*Endpoint) Done

func (e *Endpoint) Done() <-chan struct{}

func (*Endpoint) Get

func (e *Endpoint) Get(id string) (*Session, bool)

func (*Endpoint) Len

func (e *Endpoint) Len() int

func (*Endpoint) Prepare

func (e *Endpoint) Prepare(message Message) (*PreparedMessage, error)

Prepare 复制一份正文并由 Gorilla 缓存固定编码选项对应的帧;不占发送队列预算。

func (*Endpoint) Range

func (e *Endpoint) Range(fn func(*Session) bool)

Range 锁内获取快照,锁外调用 fn;返回 false 时结束遍历。

func (*Endpoint) ServeHTTP

func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP 的握手同步执行,返回后不再保存或使用 HTTP/Gin 请求对象。

func (*Endpoint) Stop

func (e *Endpoint) Stop() error

Stop 启动唯一收尾任务;不等待业务、网络或观察器。

func (*Endpoint) StopInput

func (e *Endpoint) StopInput() error

StopInput 封闭新握手、数据接纳和新复核;存量业务和输出仍可运行。 未接纳正文由底层跳过,不再解压或校验正文,控制帧继续处理。 调用方必须在有限的整体关闭期限内继续 Stop/Wait,超时或失败时 Cancel;本方法不启动定时关闭。

func (*Endpoint) Wait

func (e *Endpoint) Wait(ctx context.Context) error

Wait 仅等待,不启动关闭,也不把调用方期限传播到业务。

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 Identity

type Identity struct {
	Subject string
	Value   any
}

Identity 是认证产生的不可变快照,Value 不得包含请求对象、原始凭据或可变共享对象。

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) Close

func (s *Session) Close(code int, reason string) (bool, error)

Close 发起单连接关闭,不排空未写消息;不会等待网络和业务收尾。 OnDetach 在内部锁外同步执行,必须遵守快速内存操作约定。

func (*Session) Context

func (s *Session) Context() context.Context

func (*Session) Detached

func (s *Session) Detached() <-chan struct{}

func (*Session) Done

func (s *Session) Done() <-chan struct{}

func (*Session) ID

func (s *Session) ID() string

func (*Session) Identity

func (s *Session) Identity() Identity

func (*Session) RemoteAddr

func (s *Session) RemoteAddr() string

func (*Session) Send

func (s *Session) Send(ctx context.Context, message Message) error

func (*Session) SendPrepared

func (s *Session) SendPrepared(ctx context.Context, message *PreparedMessage) error

func (*Session) SendWhileActive

func (s *Session) SendWhileActive(ctx, activeCtx context.Context, message Message) error

SendWhileActive 与 Send 共用队列;额外的 activeCtx 非 nil 时也必须在接纳时有效。 入队后任一 context 取消都不会撤回消息。

func (*Session) Subprotocol

func (s *Session) Subprotocol() string

func (*Session) Usage

func (s *Session) Usage() Usage

type Usage

type Usage struct {
	ReceiveMessages int64
	ReceiveBytes    int64
	SendMessages    int64
	SendBytes       int64
}

Usage 包含读取/回调/写入中的占用,不等于进程物理内存。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL