42 lines
1.1 KiB
Go
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)
|
|
})
|
|
}
|