Closed DarkiT closed 1 year ago
I am having a little trouble following your use case. Is the problem you are trying to solve that you have port that is currently being used by GIN
in some capacity and you want that port to essentially serve two purposes; one for whatever GIN
uses it for and the other for mqtt
?
I am having a little trouble following your use case. Is the problem you are trying to solve that you have port that is currently being used by
GIN
in some capacity and you want that port to essentially serve two purposes; one for whateverGIN
uses it for and the other formqtt
?
Yes, that's it
@DarkiT Just for curiosity, is there a reason why you can not just change the ports either for GIN or for mochi
? Such as this
ws := listeners.NewWebsocket("ws1", ":1884", nil)
err = server.AddListener(ws)
if err != nil {
log.Fatal(err)
}
Due to policy restrictions, I cannot expose multiple ports to the outside world, so I hope that the webserver and mqtt ws share a port.
@DarkiT 这个应该能满足你的需求,你自己去优化组织下代码.You can do it like this.
// websocket.go
// Websocket is a listener for establishing websocket connections.
type Websocket struct { // [MQTT-4.2.0-1]
sync.RWMutex
id string // the internal id of the listener
address string // the network address to bind to
config *Config // configuration values for the listener
listen *http.Server // an http server for serving websocket connections
log *zerolog.Logger // server logger
establish EstablishFn // the server's establish connection handler
upgrader *websocket.Upgrader // upgrade the incoming http/tcp connection to a websocket compliant connection.
end uint32 // ensure the close methods are only called once
Router *gin.Engine
}
// ...
// Init initializes the listener.
func (l *Websocket) Init(log *zerolog.Logger) error {
l.log = log
l.Router = gin.Default()
l.Router.GET("/", func(c *gin.Context) {
l.handler(c.Writer, c.Request)
})
l.listen = &http.Server{
Addr: l.address,
Handler: l.Router,
}
return nil
}
// main.go
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2022 mochi-mqtt, mochi-co
// SPDX-FileContributor: mochi-co
package main
import (
"flag"
"log"
"os"
"os/signal"
"syscall"
"github.com/gin-gonic/gin"
mqtt "github.com/mochi-mqtt/server/v2"
"github.com/mochi-mqtt/server/v2/hooks/auth"
"github.com/mochi-mqtt/server/v2/listeners"
)
func main() {
wsAddr := flag.String("ws", ":1882", "network address for Websocket listener")
flag.Parse()
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
done <- true
}()
server := mqtt.New(nil)
_ = server.AddHook(new(auth.AllowHook), nil)
ws := listeners.NewWebsocket("ws1", *wsAddr, nil)
err := server.AddListener(ws)
if err != nil {
log.Fatal(err)
}
// 这里添加你自己的http路由和处理
// Add your own HTTP routes and handlers.
ws.Router.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "world!",
})
})
go func() {
err := server.Serve()
if err != nil {
log.Fatal(err)
}
}()
<-done
server.Log.Warn().Msg("caught signal, stopping...")
server.Close()
server.Log.Info().Msg("main.go finished")
}
@DarkiT 这个应该能满足你的需求,你自己去优化组织下代码.You can do it like this.
// websocket.go // Websocket is a listener for establishing websocket connections. type Websocket struct { // [MQTT-4.2.0-1] sync.RWMutex id string // the internal id of the listener address string // the network address to bind to config *Config // configuration values for the listener listen *http.Server // an http server for serving websocket connections log *zerolog.Logger // server logger establish EstablishFn // the server's establish connection handler upgrader *websocket.Upgrader // upgrade the incoming http/tcp connection to a websocket compliant connection. end uint32 // ensure the close methods are only called once Router *gin.Engine } // ... // Init initializes the listener. func (l *Websocket) Init(log *zerolog.Logger) error { l.log = log l.Router = gin.Default() l.Router.GET("/", func(c *gin.Context) { l.handler(c.Writer, c.Request) }) l.listen = &http.Server{ Addr: l.address, Handler: l.Router, } return nil }
// main.go // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2022 mochi-mqtt, mochi-co // SPDX-FileContributor: mochi-co package main import ( "flag" "log" "os" "os/signal" "syscall" "github.com/gin-gonic/gin" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { wsAddr := flag.String("ws", ":1882", "network address for Websocket listener") flag.Parse() sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs done <- true }() server := mqtt.New(nil) _ = server.AddHook(new(auth.AllowHook), nil) ws := listeners.NewWebsocket("ws1", *wsAddr, nil) err := server.AddListener(ws) if err != nil { log.Fatal(err) } // 这里添加你自己的http路由和处理 // Add your own HTTP routes and handlers. ws.Router.GET("/hello", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "world!", }) }) go func() { err := server.Serve() if err != nil { log.Fatal(err) } }() <-done server.Log.Warn().Msg("caught signal, stopping...") server.Close() server.Log.Info().Msg("main.go finished") }
@werbenhu ,自己尝试试了一下,实现了这个需求,不过看了您的代码,确实您更加优雅的实现了,感谢指导。
@werbenhu Thank you for your help!
Agree - thanks @werbenhu!
I want to use this as a GIN library, because I want to reuse the MQTT port with the WEB port of the GIN framework. Can you add support? For example: