BunaML’s diary

機械学習、音声・自然言語、Machine Learning, NLP, Audio, Software Development

GoサーバーとPythonサーバーの連携でPythonクライアントが切断されてもGoサーバーが落ちないようにする

GoとPythonのサーバーを連携して動作させる際に、クライアントが切断されてもサーバーが停止しないようにする  

問題点

通常、クライアントが切断するとGoサーバーは停止する。これはGoサーバーがWebSocketメッセージの読み取りエラーを検出するとhandleWebSocket関数からreturnしてしまうことに起因する。これによりゴルーチンが終了し、結果としてサーバー全体が停止してしまう。  

Pythonサーバーも同様に接続エラーが発生すると新しい接続の受付を停止する。特にUNIXドメインソケットを使用している場合に顕著。

解決策

Goサーバーの改善

WebSocketの接続エラー時にその接続のみを閉じてサーバー全体が停止するのを防ぐ。handleWebSocket関数内で各クライアント接続に対して独立したゴルーチンを起動する。

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    // ... 既存のコード ...
    go func() {
        for {
            _, requestData, err := webSocketConn.ReadMessage()
            if err != nil {
                log.Println("Error reading WebSocket message:", err)
                closeConnections(webSocketConn, connRequest)
                return
            }
            // ... リクエスト処理のコード ...
        }
    }()
}

Pythonサーバーの改善

現在の接続でエラーが発生しても新しい接続を継続して受け入れるようにする。

def accept_connections(server):
    while True:
        try:
            connection, client_address = server.accept()
            # ... 接続処理のコード ...
        except Exception as e:
            # エラー処理のコード
            continue