Files
NixMsg/internal/broker/ws.go
T

42 lines
1.1 KiB
Go

package broker
import (
"context"
"net"
"net/http"
"git.asio.asia/nixevol/NixMsg/internal/listener"
"github.com/coder/websocket"
)
// WSHandler 返回 /mqtt 的 WebSocket 升级处理。
// Accept 时 InsecureSkipVerify=true;之后检查 Subprotocol==mqtt。
// NetConn 使用 Background 派生的 context,不用请求 Context。
func (b *Broker) WSHandler(proxies *listener.ProxySet) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c, err := websocket.Accept(w, r, &websocket.AcceptOptions{
Subprotocols: []string{"mqtt"},
InsecureSkipVerify: true,
})
if err != nil {
return
}
if c.Subprotocol() != "mqtt" {
_ = c.Close(websocket.StatusPolicyViolation, "subprotocol must be mqtt")
return
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
nc := websocket.NetConn(ctx, c, websocket.MessageBinary)
if proxies != nil {
ip := proxies.ClientIP(r)
if ip != "" {
nc = listener.WithRemoteAddr(nc, &net.TCPAddr{IP: net.ParseIP(ip)})
}
}
_ = b.AttachWS(nc)
})
}