2024-03-15
概要
- Fiber はGo言語のウェブフレームワーク
- WebSocket でメッセージを送信できるか試してみた
Fiber で WebSocket
Fiber には WebSocket ハンドラーのラッパー的な関数が用意されてます。
WebSocketのUpgradeやコネクション確立まわりをサポートしてくれるようで、大変便利でした。
リンク
参考記事など
サンプルコード
WebSocket でメッセージを送信するプログラムを書きました。
肝はメッセージ送信部分です。
各コネクションへメッセージを一斉送信するために、コネクションを struct に詰め込んでます。
package main import ( "log" "time" "github.com/gofiber/contrib/websocket" "github.com/gofiber/fiber/v2" "github.com/google/uuid" ) // websocket のコネクションたちを保持する func NewWsConns() WsConns { return WsConns { conns: make(map[string]*websocket.Conn), } } type WsConns struct { conns map[string]*websocket.Conn } func (c *WsConns) Add(conn *websocket.Conn) string { id := uuid.NewString() c.conns[id] = conn return id } func (c *WsConns) Remove(id string) { if conn, ok := c.conns[id]; ok { delete(c.conns, id) conn.Close() } } func (c *WsConns) Send(message string) { for id, conn := range c.conns { if err := conn.WriteMessage(websocket.TextMessage, []byte(message)); err != nil { c.Remove(id) } } } func main() { app := fiber.New() // websocket のコネクションたちを保持する wsconns := NewWsConns() // websocket のコネクションを受け付けるパス app.Get("/ws", websocket.New(func(c *websocket.Conn) { requestId := wsconns.Add(c) defer wsconns.Remove(requestId) for { messageType, _, err := c.ReadMessage() if err != nil { break } if messageType == websocket.CloseGoingAway { break } } })) // 1秒おきにメッセージを送信する go func() { for { time.Sleep(1 * time.Second) wsconns.Send("hello") } }() if err := app.Listen(":3000"); err != nil { log.Fatalf("Error: %s", err.Error()) } }
受信できるか確認
wscat で接続してメッセージを受信できるか確認します。
$ wscat -c http://localhost:3000/ws Connected (press CTRL+C to quit) < hello < hello < hello
期待通り hello が送られてきました。
終わりに
- 手軽でした
- WebSocket の性質上あたりまえですが、コネクションを維持するためリソースを食いそうに思えます
- 場合によっては WebSocket サーバを別に立てるのも有りだと思います
作成日
2024-03-15
更新日
2024-03-22