devlog

[Fiber] WebSocket でメッセージを送信してみた

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