quic

package
v0.8.6 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package quic 提供基于 QUIC(quic-go)的连接层,作为 pkg/ws(WebSocket/TCP)之外 面向实时/游戏同步的可选传输。opt-in 子包,按需 import,不污染现有 TCP 栈。

为什么是 QUIC:一条连接上同时给你两种通道,正好覆盖游戏同步的两类数据——

  • 可靠有序流(OpenStream/AcceptStream):关键指令、登录、聊天,像 TCP 但多路 复用、跨流无队头阻塞(HoL);
  • 不可靠数据报(SendDatagram/ReceiveDatagram,RFC 9221):高频状态/位置更新, 丢了就丢、不重传、不阻塞后续——正是状态同步想要的语义(TCP 给不了)。

另外 QUIC 内建 TLS 1.3(加密是强制的)、连接迁移、0-RTT。

语义与边界:

  • TLS 必填。生产传 WithTLSConfig;没传时 Server 自动生成自签证书并告警(仅供 开发/示例,客户端需 WithInsecureSkipVerify)。见 DevTLSConfig。
  • 数据报受 MTU 限制(通常 ≲1200 字节),大负载走可靠流或自行分片。
  • Server 结构上满足 beauty.Service(Start/String)+ ReadyNotifier,可直接 beauty.WithService(srv) 挂进框架、随 app 优雅停机。

本包只做「薄传输」:Conn 是对 quic-go 连接的封装,流/数据报直接透出,不叠加 应用协议(序列化、房间、AOI 等由上层如 pkg/gameloop + 你的编解码决定)。

性能(生产要点):

  • UDP 缓冲区:quic-go 期望内核 UDP 收发缓冲各 7MB;OS 常按 net.core.rmem_max / wmem_max 压低上限,高负载下会丢包。生产请先放开(Linux: `sysctl -w net.core.rmem_max=7500000 net.core.wmem_max=7500000`), 并用 ListenUDP 建 socket(已尽力把缓冲提到 7MB)交给 WithPacketConn。
  • Socket 复用:自备 quic.Transport(WithTransport / WithDialTransport)可让一条 UDP socket 同时承载「服务端监听 + 多个客户端拨号」(靠连接 ID 解复用),省 fd/内存, 适合既收玩家又拨对端的网关。
  • GSO 批量发送在 Linux 上由 quic-go 自动开启,无需配置。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DevTLSConfig

func DevTLSConfig() (*tls.Config, error)

DevTLSConfig 生成一份带自签名证书的服务端 tls.Config,仅供开发/示例——证书对 localhost / 127.0.0.1 有效,客户端需 WithInsecureSkipVerify 才能连上。生产环境 请用你自己的证书通过 WithTLSConfig 传入,不要用这个。

Server 在未设置 WithTLSConfig 时会自动调用它并打印告警。

func ListenUDP

func ListenUDP(addr string) (*net.UDPConn, error)

ListenUDP 建一个 UDP socket 并尽力把收发缓冲区提到 7MB(减少高负载丢包)。OS 可能 仍按 net.core.rmem_max / wmem_max 压低(见包注释的 sysctl 提示)。返回的 socket 可 直接交给 WithPacketConn,或包进 quic.Transport 在多个 Server/Dial 间复用。

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn 是一条 QUIC 连接的薄封装:既能开可靠流,也能收发不可靠数据报。

func Dial

func Dial(ctx context.Context, addr string, opts ...DialOption) (*Conn, error)

Dial 连接一个 QUIC 服务端。

func (*Conn) AcceptStream

func (c *Conn) AcceptStream(ctx context.Context) (*quicgo.Stream, error)

AcceptStream 阻塞接收对端打开的下一条流,直到到达或 ctx 取消。

func (*Conn) Close

func (c *Conn) Close(reason string) error

Close 关闭连接(附带 reason,对端可读)。幂等。

func (*Conn) Context

func (c *Conn) Context() context.Context

Context 返回连接的生命周期 ctx(连接关闭时取消)。

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr 返回本地地址。

func (*Conn) OpenStream

func (c *Conn) OpenStream(ctx context.Context) (*quicgo.Stream, error)

OpenStream 打开一条双向可靠有序流(阻塞直到流控允许或 ctx 取消)。 返回的 *quicgo.Stream 是 io.ReadWriteCloser:Close 关闭发送方向,仍可继续读。

func (*Conn) Raw

func (c *Conn) Raw() *quicgo.Conn

Raw 返回底层 quic-go 连接,供需要高级能力时使用。

func (*Conn) ReceiveDatagram

func (c *Conn) ReceiveDatagram(ctx context.Context) ([]byte, error)

ReceiveDatagram 阻塞接收下一条数据报,直到收到或 ctx 取消。

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr 返回对端地址。

func (*Conn) SendDatagram

func (c *Conn) SendDatagram(b []byte) error

SendDatagram 发送一条不可靠数据报(不重传、不保证到达/顺序)。适合高频状态更新。 负载过大(超过路径 MTU)会返回错误——大负载请走可靠流。

type DialOption

type DialOption func(*dialConfig)

DialOption 配置 Dial。

func WithClientQUICConfig

func WithClientQUICConfig(c *quicgo.Config) DialOption

WithClientQUICConfig 覆盖客户端 quic.Config。

func WithClientTLSConfig

func WithClientTLSConfig(c *tls.Config) DialOption

WithClientTLSConfig 设置客户端 TLS(缺省时用一个只设 ALPN 的空配置)。

func WithDialTransport

func WithDialTransport(t *quicgo.Transport) DialOption

WithDialTransport 复用一个自备的 quic.Transport 拨号,可与 Server 共享同一条 UDP socket。

func WithInsecureSkipVerify

func WithInsecureSkipVerify(v bool) DialOption

WithInsecureSkipVerify 跳过服务端证书校验(仅供开发/自签证书场景)。

type Handler

type Handler func(ctx context.Context, c *Conn) error

Handler 处理一条被接受的连接。ctx 在 server 停机时取消——handler 应据此退出。

type Option

type Option func(*Server)

Option 配置 Server。

func WithPacketConn

func WithPacketConn(pc net.PacketConn) Option

WithPacketConn 让 Server 在自备的 UDP socket 上监听(而非按 addr 新建),便于用 ListenUDP 预调缓冲区。socket 生命周期由调用方管理(Server 停机只关 Listener,不关 socket)。

func WithQUICConfig

func WithQUICConfig(c *quicgo.Config) Option

WithQUICConfig 覆盖 quic.Config(默认开启数据报、30s idle、15s keepalive)。

func WithServiceName

func WithServiceName(name string) Option

WithServiceName 设置服务名(日志/标识用)。

func WithTLSConfig

func WithTLSConfig(c *tls.Config) Option

WithTLSConfig 设置服务端 TLS(生产必填;须包含证书,NextProtos 会在缺省时补上默认 ALPN)。

func WithTransport

func WithTransport(t *quicgo.Transport) Option

WithTransport 让 Server 复用一个自备的 quic.Transport(优先于 WithPacketConn), 可与客户端 Dial 共享同一条 UDP socket。transport 生命周期由调用方管理。

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server 是一个 QUIC 服务端,结构上满足 beauty.Service + ReadyNotifier。 零值不可用,用 NewServer 构造。

func NewServer

func NewServer(addr string, handler Handler, opts ...Option) *Server

NewServer 创建 QUIC 服务端。addr 形如 "127.0.0.1:8443"(":0" 由系统选端口, 之后可用 Addr() 取回)。handler 处理每条连接。

func (*Server) Addr

func (s *Server) Addr() net.Addr

Addr 返回实际监听地址(":0" 时用来取回系统分配的端口);未启动返回 nil。

func (*Server) Ready

func (s *Server) Ready() <-chan struct{}

Ready 在开始监听后关闭——满足 beauty.ReadyNotifier。

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start 监听并循环接受连接,每条连接起一个 goroutine 跑 handler;ctx 取消时停止 接受、关闭在途连接并等其退出——满足 beauty.Service。

func (*Server) String

func (s *Server) String() string

String 满足 beauty.Service。

Jump to

Keyboard shortcuts

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