LoginSignup
3
4

どのような実現方法があるのか?

GPTによると...

・Gorilla WebSocket: 高機能で安定しているが、やや複雑。
・nhooyr.io/websocket: シンプルでコンテキスト対応、軽量だが機能は少なめ。
・golang.org/x/net/websocket: 基本的な機能を提供するが、メンテナンス頻度が低い。
・github.com/gobwas/ws: 高速で低レベル制御が可能だが、学習コストが高い。
・github.com/olahol/melody: 使いやすく多機能だが、パフォーマンスやスケーリングの面で劣ることがある。

プロジェクトの作成

必要なければ飛ばしてください.

詳細を表示 go言語のインストールはこちらから

インストール出来たら.

  1. ディレクトリ作成

    mkdir myproject
    
  2. ディレクトリに移動

    cd myproject
    
  3. プロジェクトの初期化

    go mod init example.com/myproject
    
  4. パッケージのダウンロード

    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
}
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4