fix(chat): 调整输入交互并加固 WS/告警处理
This commit is contained in:
@@ -6,7 +6,11 @@ extends Node
|
||||
# 负责与后端 WebSocket 服务进行位置同步和多人会话管理
|
||||
#
|
||||
# 协议文档: new_docs/game_architecture_design.md
|
||||
# 后端地址: wss://whaletownend.xinghangee.icu/location-broadcast
|
||||
# 后端地址默认值: wss://whaletownend.xinghangee.icu/game
|
||||
# 可通过以下方式覆盖:
|
||||
# 1) 环境变量 WHALETOWN_LOCATION_WS_URL
|
||||
# 2) Config/game_config.json 或 config/game_config.json 中的
|
||||
# network.location_ws_url / network.game_ws_url
|
||||
# ============================================================================
|
||||
|
||||
signal connected_to_server()
|
||||
@@ -17,23 +21,32 @@ signal user_joined(data: Dictionary)
|
||||
signal user_left(data: Dictionary)
|
||||
signal position_updated(data: Dictionary)
|
||||
|
||||
const WS_URL = "wss://whaletownend.xinghangee.icu/location-broadcast"
|
||||
const DEFAULT_WS_URL: String = "wss://whaletownend.xinghangee.icu/game"
|
||||
const WS_URL_ENV_KEY: String = "WHALETOWN_LOCATION_WS_URL"
|
||||
const PING_INTERVAL = 25.0 # 秒
|
||||
|
||||
var _socket: WebSocketPeer
|
||||
var _connected: bool = false
|
||||
var _ping_timer: float = 0.0
|
||||
var _auth_token: String = ""
|
||||
var _connection_error_reported: bool = false
|
||||
var _is_connecting: bool = false
|
||||
var _ws_url: String = DEFAULT_WS_URL
|
||||
|
||||
func _ready():
|
||||
_socket = WebSocketPeer.new()
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS # 保证暂停时也能处理网络
|
||||
_ws_url = _resolve_ws_url()
|
||||
|
||||
func _process(delta):
|
||||
_socket.poll()
|
||||
|
||||
var state = _socket.get_ready_state()
|
||||
|
||||
if state == WebSocketPeer.STATE_OPEN:
|
||||
_connection_error_reported = false
|
||||
_is_connecting = false
|
||||
|
||||
if not _connected:
|
||||
_on_connected()
|
||||
|
||||
@@ -51,19 +64,71 @@ func _process(delta):
|
||||
elif state == WebSocketPeer.STATE_CLOSED:
|
||||
if _connected:
|
||||
_on_disconnected()
|
||||
elif _is_connecting and not _connection_error_reported:
|
||||
var close_code := _socket.get_close_code()
|
||||
var close_reason := _socket.get_close_reason()
|
||||
push_warning(
|
||||
"LocationManager: WebSocket 握手失败,close_code=%d, reason=%s" % [close_code, close_reason]
|
||||
)
|
||||
connection_error.emit()
|
||||
_connection_error_reported = true
|
||||
_is_connecting = false
|
||||
|
||||
func connect_to_server():
|
||||
if _socket.get_ready_state() == WebSocketPeer.STATE_OPEN:
|
||||
var state: WebSocketPeer.State = _socket.get_ready_state()
|
||||
if state == WebSocketPeer.STATE_OPEN or state == WebSocketPeer.STATE_CONNECTING:
|
||||
return
|
||||
|
||||
var err = _socket.connect_to_url(WS_URL)
|
||||
|
||||
_connection_error_reported = false
|
||||
_is_connecting = true
|
||||
var err = _socket.connect_to_url(_ws_url)
|
||||
if err != OK:
|
||||
push_error("LocationManager: WebSocket 连接请求失败,错误码: %d" % err)
|
||||
push_error("LocationManager: WebSocket 连接请求失败,url=%s, 错误码: %d" % [_ws_url, err])
|
||||
connection_error.emit()
|
||||
_connection_error_reported = true
|
||||
_is_connecting = false
|
||||
else:
|
||||
# Godot WebSocket connect is non-blocking, wait for state change in _process
|
||||
pass
|
||||
|
||||
func _resolve_ws_url() -> String:
|
||||
var env_url: String = OS.get_environment(WS_URL_ENV_KEY).strip_edges()
|
||||
if not env_url.is_empty():
|
||||
return env_url
|
||||
|
||||
for config_path in ["res://Config/game_config.json", "res://config/game_config.json"]:
|
||||
var config_url: String = _load_ws_url_from_config(config_path)
|
||||
if not config_url.is_empty():
|
||||
return config_url
|
||||
|
||||
return DEFAULT_WS_URL
|
||||
|
||||
func _load_ws_url_from_config(config_path: String) -> String:
|
||||
if not FileAccess.file_exists(config_path):
|
||||
return ""
|
||||
|
||||
var content: String = FileAccess.get_file_as_string(config_path)
|
||||
if content.is_empty():
|
||||
return ""
|
||||
|
||||
var json := JSON.new()
|
||||
if json.parse(content) != OK:
|
||||
push_warning("LocationManager: 读取配置失败 %s - %s" % [config_path, json.get_error_message()])
|
||||
return ""
|
||||
|
||||
var data_variant: Variant = json.data
|
||||
if not (data_variant is Dictionary):
|
||||
return ""
|
||||
|
||||
var root: Dictionary = data_variant
|
||||
var network_variant: Variant = root.get("network", {})
|
||||
if not (network_variant is Dictionary):
|
||||
return ""
|
||||
|
||||
var network_config: Dictionary = network_variant
|
||||
var ws_url: String = str(network_config.get("location_ws_url", network_config.get("game_ws_url", ""))).strip_edges()
|
||||
return ws_url
|
||||
|
||||
func close_connection():
|
||||
_socket.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user