どのような実現方法があるのか?
GPTによると...
・Gorilla WebSocket: 高機能で安定しているが、やや複雑。
・nhooyr.io/websocket: シンプルでコンテキスト対応、軽量だが機能は少なめ。
・golang.org/x/net/websocket: 基本的な機能を提供するが、メンテナンス頻度が低い。
・github.com/gobwas/ws: 高速で低レベル制御が可能だが、学習コストが高い。
・github.com/olahol/melody: 使いやすく多機能だが、パフォーマンスやスケーリングの面で劣ることがある。
プロジェクトの作成
必要なければ飛ばしてください.
詳細を表示
go言語のインストールはこちらからインストール出来たら.
-
ディレクトリ作成
mkdir myproject
-
ディレクトリに移動
cd myproject
-
プロジェクトの初期化
go mod init example.com/myproject
-
パッケージのダウンロード
go get -u github.com/gorilla/websocket
コード
今回はGorilla WebSocketを使って簡単に座標更新をするものを作ってみたよ.
main.go
package main
import (
"log"
"net/http"
"os"
"sync"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// Messageの型を作る
type Message struct {
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
}
// Client represents a single WebSocket connection
type Client struct {
conn *websocket.Conn
}
// ClientManager manages all active WebSocket connections
type ClientManager struct {
clients map[*Client]bool
broadcast chan Message
register chan *Client
unregister chan *Client
mu sync.Mutex
}
// NewClientManager creates a new ClientManager
func NewClientManager() *ClientManager {
return &ClientManager{
clients: make(map[*Client]bool),
broadcast: make(chan Message),
register: make(chan *Client),
unregister: make(chan *Client),
}
}
// Start runs the client manager
func (manager *ClientManager) Start() {
for {
select {
case client := <-manager.register:
manager.mu.Lock()
manager.clients[client] = true
manager.mu.Unlock()
case client := <-manager.unregister:
manager.mu.Lock()
if _, ok := manager.clients[client]; ok {
delete(manager.clients, client)
client.conn.Close()
}
manager.mu.Unlock()
case message := <-manager.broadcast:
manager.mu.Lock()
for client := range manager.clients {
err := client.conn.WriteJSON(message)
if err != nil {
log.Printf("error: %v", err)
client.conn.Close()
delete(manager.clients, client)
}
}
manager.mu.Unlock()
}
}
}
var manager = NewClientManager()
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
client := &Client{conn: conn}
manager.register <- client
defer func() {
manager.unregister <- client
}()
for {
var msg Message
err := conn.ReadJSON(&msg)
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %+v", msg)
manager.broadcast <- msg
}
}
func main() {
go manager.Start()
port := os.Getenv("PORT")
if port == "" {
port = "8000"
}
http.HandleFunc("/ws", wsHandler)
log.Println("Starting server on :" + port)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
log.Fatal(err)
}
}
確認方法
goの起動
go run main.go
Postman
下記のURLにコネクト
ws://localhost:8000/ws
下記のjsonを送信してみよう
{
"x": 1.1,
"y": 2.0,
"z": 3.0
}