はじめに
勉強がてらGoでWebsocketを使ったチャットアプリを作ってみた時の備忘録です。
作ったもの
フレームワークとしてはGinを使い、ORMにはgorm v2を使っています。 またWebsocket周りはmelodyを使っています。
やったこと
細かいところは基本的にはコミットログをにまとまっているのでそちらを見ていただければと思います。
実装の肝としては、routes/setup.go
に以下のようにWebsocket用のルーティングを追加して、
// チャットルーム用のWebsocket接続先 router.GET("/rooms/:id/messages/ws", messageController.Websocket) m.HandleMessage(func(s *melody.Session, msg []byte) { m.Broadcast(msg) }) m.HandleConnect(func(s *melody.Session) { log.Printf("websocket connection open. [session: %#v]\n", s) }) m.HandleDisconnect(func(s *melody.Session) { log.Printf("websocket connection close. [session: %#v]\n", s) }) // メッセージがブロードキャストされたときの処理 m.HandleMessage(messageController.Broadcast)
フロント側から接続するときのルーティングとWebsocket周りの接続を設定しています。
あとは、メッセージを作成する処理をコントローラーのアクションを以下のように作成しています。
func (messageController *messageController) Broadcast(s *melody.Session, msg []byte) { roomPath := strings.Trim(s.Request.URL.Path, "/roomsmessagews") roomID, _ := strconv.ParseUint(roomPath, 10, 64) var message model.Message message.Content = fmt.Sprintf("%s", msg) message.RoomID = roomID messageController.messageRepository.Store(messageController.db, &message) messageController.m.BroadcastFilter(msg, func(q *melody.Session) bool { return q.Request.URL.Path == s.Request.URL.Path }) }
あとはフロント側でWebsocketのエンドポイントに接続させておけばいい感じです。
やってみて
意外と簡単に実装できたので今後仕事のコードとかで導入してみてもいいかなと思いました。