Files
4566704 96c63fb153 feat(spmux): 自 go-hua 迁入单端口多路复用并解耦日志依赖
- go-hua/log 已弃用: *log.Logger 参数改为两方法接口 spmux.Logger
  (*logrus.Logger 天然满足), 传 nil 静默(logErrorf/logDebugf 判空)
- 协议识别改用 zogo/httpprobe; 测试与例程同步适配
- 附测试、examples/spmux 例程(含 Logger 适配演示)与包 README
2026-09-20 12:37:10 +08:00

1.6 KiB
Raw Permalink Blame History

spmux

单端口多路复用:同一端口上按报文特征(首部字节,基于 zogo/httpprobe)把流量 分发给 HTTP / HTTPS / TCP 三个 net.Listener,适合"网页管理端 + 自有 TCP 协议" 共存的单端口部署。

迁移自 go-hua/spmux。原依赖的 go-hua/log 已弃用,日志改为两方法接口 Logger(*logrus.Logger 天然满足,可传 nil 静默);协议识别改用 httpprobe。

用法

import (
    "net"
    "net/http"

    "git.zeroonesoft.cn/golib/zogo/spmux"
    "git.zeroonesoft.cn/golib/zogo/logger" // 可选:logrus 实例满足 Logger
)

pm := spmux.NewPortMux(8443, logger.Logrus) // 或 nil
pm.Start()

// HTTP(S) 流量分别交给两个 Listener(TLS 由消费方自行包裹)
go http.Serve(pm.HttpListener(), mux)
ln := pm.HttpsListener()

// 其余流量走 TCP 自有协议
go func() {
    for {
        c, err := ln.Accept() // 注意用 TcpListener 时见下方 Deprecated 说明
        ...
    }
}()

完整可运行例程:examples/spmux/main.go

注意

  • 协议识别需要先窥探首包(FirstPeekSize 起,最多读到 8 字节),消费方收到的 连接是 PortConn(已回放窥探字节),业务读取完整无感。
  • TcpListener 已标 Deprecated:RFB 等"服务端先发数据"的协议无法识别为 TCP; 这类端口不要与其他协议混用。
  • 分发等待消费方 Accept 的超时为 AcceptTimeout(100 秒),超时关闭连接。
  • 自 go-hua 迁移的消费方:NewPortMux(port, *log.Logger) → NewPortMux(port, spmux.Logger)(接口),适配方式见例程 stdoutLogger。