# spmux 单端口多路复用:同一端口上按报文特征(首部字节,基于 `zogo/httpprobe`)把流量 分发给 HTTP / HTTPS / TCP 三个 `net.Listener`,适合"网页管理端 + 自有 TCP 协议" 共存的单端口部署。 > 迁移自 go-hua/spmux。原依赖的 go-hua/log 已弃用,日志改为两方法接口 > `Logger`(`*logrus.Logger` 天然满足,可传 nil 静默);协议识别改用 httpprobe。 ## 用法 ```go 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](../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`。