From 60fb58f6d5e62f46090b8d38c89601ebc3d4132c Mon Sep 17 00:00:00 2001 From: misyaguziya <53165965+misyaguziya@users.noreply.github.com> Date: Tue, 20 May 2025 11:08:11 +0900 Subject: [PATCH] [Update] WebSocket: Disable server by default and add port availability check --- src-python/config.py | 2 +- src-python/controller.py | 83 ++++++++++++++++++++++++++++++++-------- src-python/model.py | 30 +++++++++++++-- 3 files changed, 94 insertions(+), 21 deletions(-) diff --git a/src-python/config.py b/src-python/config.py index f1b7de65..cfeeec51 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -1172,7 +1172,7 @@ class Config: self._LOGGER_FEATURE = False self._VRC_MIC_MUTE_SYNC = False self._NOTIFICATION_VRC_SFX = True - self._WEBSOCKET_SERVER = True + self._WEBSOCKET_SERVER = False self._WEBSOCKET_HOST = "127.0.0.1" self._WEBSOCKET_PORT = 2231 diff --git a/src-python/controller.py b/src-python/controller.py index 4890617e..e21e66e0 100644 --- a/src-python/controller.py +++ b/src-python/controller.py @@ -295,10 +295,12 @@ class Controller: "transliteration":transliteration }) - if config.WEBSOCKET_SERVER is True: + if model.checkWebSocketServerAlive() is True: model.websocketSendMessage( { "type":"SENT", + "src_languages":config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO], + "dst_languages":config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO], "message":message, "translation":translation, "transliteration":transliteration @@ -389,10 +391,12 @@ class Controller: "transliteration":transliteration, }) - if config.WEBSOCKET_SERVER is True: + if model.checkWebSocketServerAlive() is True: model.websocketSendMessage( { "type":"RECEIVED", + "src_languages":config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO], + "dst_languages":config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO], "message":message, "translation":translation, "transliteration":transliteration @@ -456,10 +460,12 @@ class Controller: overlay_image = model.createOverlayImageLargeLog("send", message, translation[0] if len(translation) > 0 else "") model.updateOverlayLargeLog(overlay_image) - if config.WEBSOCKET_SERVER is True: + if model.checkWebSocketServerAlive() is True: model.websocketSendMessage( { "type":"CHAT", + "src_languages":config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO], + "dst_languages":config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO], "message":message, "translation":translation, "transliteration":transliteration @@ -1816,11 +1822,31 @@ class Controller: @staticmethod def setWebSocketHost(data, *args, **kwargs) -> dict: - config.WEBSOCKET_HOST = data - if model.checkWebSocketServer() is True: - model.stopWebSocketServer() - model.startWebSocketServer() - return {"status":200, "result":config.WEBSOCKET_HOST} + if isValidIpAddress(data) is False: + response = { + "status":400, + "result":{ + "message":"Invalid IP address", + "data": config.WEBSOCKET_HOST + } + } + else: + if model.checkWebSocketServerAlive() is True: + model.stopWebSocketServer() + + if model.checkWebSocketServerPortAvailable() is True: + model.startWebSocketServer(data, config.WEBSOCKET_PORT) + config.WEBSOCKET_HOST = data + response = {"status":200, "result":config.WEBSOCKET_HOST} + else: + response = { + "status":400, + "result":{ + "message":"WebSocket server port is not available", + "data": config.WEBSOCKET_HOST + } + } + return response @staticmethod def getWebSocketPort(*args, **kwargs) -> dict: @@ -1828,11 +1854,21 @@ class Controller: @staticmethod def setWebSocketPort(data, *args, **kwargs) -> dict: - config.WEBSOCKET_PORT = int(data) - if model.checkWebSocketServer() is True: + if model.checkWebSocketServerAlive() is True: model.stopWebSocketServer() - model.startWebSocketServer() - return {"status":200, "result":config.WEBSOCKET_PORT} + if model.checkWebSocketServerPortAvailable() is True: + model.startWebSocketServer(config.WEBSOCKET_HOST, int(data)) + config.WEBSOCKET_PORT = int(data) + response = {"status":200, "result":config.WEBSOCKET_PORT} + else: + response = { + "status":400, + "result":{ + "message":"WebSocket server port is not available", + "data": config.WEBSOCKET_PORT + } + } + return response @staticmethod def getWebSocketServer(*args, **kwargs) -> dict: @@ -1840,9 +1876,19 @@ class Controller: @staticmethod def setEnableWebSocketServer(*args, **kwargs) -> dict: - model.startWebSocketServer() - config.WEBSOCKET_SERVER = True - return {"status":200, "result":config.WEBSOCKET_SERVER} + if model.checkWebSocketServerPortAvailable() is True: + model.startWebSocketServer(config.WEBSOCKET_HOST, config.WEBSOCKET_PORT) + config.WEBSOCKET_SERVER = True + response = {"status":200, "result":config.WEBSOCKET_SERVER} + else: + response = { + "status":400, + "result":{ + "message":"WebSocket server port is not available", + "data": config.WEBSOCKET_SERVER + } + } + return response @staticmethod def setDisableWebSocketServer(*args, **kwargs) -> dict: @@ -1951,7 +1997,12 @@ class Controller: printLog("Init WebSocket Server") if config.WEBSOCKET_SERVER is True: - model.startWebSocketServer() + if model.checkWebSocketServerPortAvailable() is True: + model.startWebSocketServer(config.WEBSOCKET_HOST, config.WEBSOCKET_PORT) + else: + config.WEBSOCKET_SERVER = False + model.stopWebSocketServer() + printLog("WebSocket server port is not available") printLog("Update settings") self.updateConfigSettings() diff --git a/src-python/model.py b/src-python/model.py index cbbb9562..bdf8d523 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -1,6 +1,8 @@ import copy import gc import asyncio +import socket +import errno import json from subprocess import Popen from os import makedirs as os_makedirs @@ -838,16 +840,36 @@ class Model: """WebSocketメッセージ受信時の処理""" pass - def startWebSocketServer(self): + def checkWebSocketServerPortAvailable(self): + """WebSocketサーバーのポートが使用中かどうかを確認する""" + response = True + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as chk: + try: + chk.bind((config.WEBSOCKET_HOST, config.WEBSOCKET_PORT)) + chk.shutdown(socket.SHUT_RDWR) + chk.close() + except OSError as e: + if e.errno == errno.EADDRINUSE: + response = False + else: + errorLogging(e) + response = False + return response + + def startWebSocketServer(self, host, port): """WebSocketサーバーを起動し、別スレッドで実行する""" + if self.websocket_server_alive is True: + # サーバーが既に起動している場合は何もしない + return + self.websocket_server_loop = True self.websocket_server_alive = False # 初期状態を明示 async def WebSocketServerMain(): try: self.websocket_server = WebSocketServer( - host=config.WEBSOCKET_HOST, - port=config.WEBSOCKET_PORT, + host=host, + port=port, ) self.websocket_server.set_message_handler(self.message_handler) self.websocket_server.start() @@ -893,7 +915,7 @@ class Model: self.websocket_server = None self.websocket_server_alive = False - def checkWebSocketServer(self): + def checkWebSocketServerAlive(self): """WebSocketサーバーの稼働状態を確認する""" return self.websocket_server_alive