![見出し画像](https://assets.st-note.com/production/uploads/images/100776398/rectangle_large_type_2_739c79b88190f5c081a49a06fb2a13c9.png?width=1200)
GO言語のWebアプリフレームワークFiberで Websocketをまじめに使う方法
今朝は6時まで寝てしまいました。ときがわの温泉水で沸かしたお風呂の効果です。
本業でGO言語のWebアプリーフレームワークFiberを使っています。
普通のリクエストを処理する部分は簡単できましたが、開発しているものは
WebSocketも使う必要があって、そこで調べたことを書いておきます。
FiberのトップページにもWebScoketの例が書いていあります。
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
// Websocket logic
for {
mtype, msg, err := c.ReadMessage()
if err != nil {
break
}
log.Printf("Read: %s", msg)
err = c.WriteMessage(mtype, msg)
if err != nil {
break
}
}
log.Println("Error:", err)
}))
です。実は、これを見て感動してFiberを使う気になりました。
上のサンプルプログラムだと受信したデータを、そのまま送信しているだけなので、実際に私の作りたいものに組み込もうと思うと、いくつも疑問がでてきます。
受信データがないと処理が止まってしまうのでは?
受信したデータを他の処理にどうやって送る?
自分から送りたい時はどうするの?
などなどです。
サンプルは簡単だけど、それを応用する方法で悩むことはかなりあります。
日曜日にキャンプ講習でリフレッシュして昨日は頭もスッキリしていたので、まじめに調べました。
トップページのサンプルの後に、
のドキュメントを見ました。でも、なんとなく説明に記載されている関数とかが少ない。不思議に思ってGitHUBのページ
も見てみました。
Based on Fasthttp WebSocket for Fiber with available *fiber.Ctx methods like Locals, Params, Query and Cookies.
とありました。FasthttpのWebSocketをベースにしていたのです。
ベースにしたパッケージは
です。このページには、ちゃんとしたドキュメントへのリンクや
サンプルプログラムのリンクがありました。
APIのドキュメントは
です。
そして、私がトップページのサンプルで思ったすべての疑問を解決してくれるサンプルプログラムもありました。
です。
![](https://assets.st-note.com/img/1679350971178-ElbuByrwwz.png?width=1200)
このな感じのサンプルです。ポイントはHUBです。
/ Hub maintains the set of active clients and broadcasts messages to the
// clients.
type Hub struct {
// Registered clients.
clients map[*Client]bool
// Inbound messages from the clients.
broadcast chan []byte
// Register requests from the clients.
register chan *Client
// Unregister requests from clients.
unregister chan *Client
}
func newHub() *Hub {
return &Hub{
broadcast: make(chan []byte),
register: make(chan *Client),
unregister: make(chan *Client),
clients: make(map[*Client]bool),
}
}
func (h *Hub) run() {
for {
select {
case client := <-h.register:
h.clients[client] = true
case client := <-h.unregister:
if _, ok := h.clients[client]; ok {
delete(h.clients, client)
close(client.send)
}
case message := <-h.broadcast:
for client := range h.clients {
select {
case client.send <- message:
default:
close(client.send)
delete(h.clients, client)
}
}
}
}
}
短いソースコードですが、接続したクライアントを登録したり、切断したら登録解除したり、他のクライアントに送信したりできます。
このソースコードを発見した時には、かなり幸せな気分になりました。
本業のプログラムに組み込んで快適に動作しています。
明日に続く
いいなと思ったら応援しよう!
![twsnmp](https://assets.st-note.com/production/uploads/images/14333815/profile_ee1accba5615957e5029db85d57fdb0a.jpg?width=600&crop=1:1,smart)