我正在尝试设置一个简单的 websocket 服务器,它应该以未知的时间间隔为客户端提供一些内容。
我的代码目前看起来像这样:
router.go
func SetupRoutes(app *fiber.App) error {
app.Get("/whop/validate", handler.HandleWhopValidate)
/*Other non-websocket routes*/
/*...*/
app.Get("/ws/monitor", websocket.New(wsHandler.HandleWsMonitor))
app.Use(func(c *fiber.Ctx) error {
c.SendStatus(404)
return c.Next()
})
return nil
}
handler.go
package handlers
import (
"fmt"
"log"
"github.com/gofiber/websocket/v2"
)
var register = make(chan *websocket.Conn)
var unregister = make(chan *websocket.Conn)
func HandleWsMonitor(c *websocket.Conn) {
go SocketListener()
defer func() {
unregister <- c
//may need to check whether connection is already closed before re-closing?
c.Close()
}()
//sends conn into channel
register <- c
for {
messageType, message, err := c.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Println("read error:", err)
}
return
}
if messageType == websocket.TextMessage {
log.Println("got textmessage:", string(message))
} else {
log.Println("received message of type:", messageType)
}
}
}
func SocketListener() {
for {
select {
case c := <-register:
messageType, message, err := c.ReadMessage()
if err != nil {
log.Println(err)
unregister <- c
return
}
fmt.Printf("Got message of type: %d\nMessage:%s\n", messageType, string(message))
fmt.Printf("Connection Params: %s\n", c.Params("id"))
//append to list of co
case c := <-unregister:
//remove conection from list of clients
c.Close()
fmt.Printf("Closed connection\n")
}
}
}
我遇到的问题是,当我连接到 websocket 时,我的注册选择案例没有命中(我想使用之前提供给客户端的 uuid 将客户端连接注册到地图)。
client.go
package main
import (
"flag"
"log"
"net/url"
"github.com/fasthttp/websocket"
)
type Client struct {
C *websocket.Conn
}
func main() {
addr := flag.String("addr", "localhost:8080", "http service address")
u := url.URL{
Scheme: "ws",
Host: *addr,
Path: "/ws/monitor",
RawQuery: "id=12",
}
wsClient := &Client{}
log.Printf("connecting to %s\n", u.String())
// Connect to the WebSocket server
conn, resp, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Dial:", err)
}
wsClient.C = conn
if resp != nil {
log.Println("Got response:", resp)
}
defer wsClient.closeConn()
}
func (client *Client) closeConn() {
err := client.C.WriteMessage(
websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""),
)
if err != nil {
log.Println("Write close:", err)
return
}
client.C.Close()
log.Println("Connection closed")
}
我在 handler.go 中缺少什么吗?或者我应该在与我的客户端连接到服务器时采取不同的方法吗?