fix(chat): 修复WebSocket连接和消息格式

- 修复连接状态检测时机问题
- 修复聊天消息格式为 {t: chat, content, scope}
- 添加 _send_login_message 函数
- 移除空消息心跳避免服务器错误
This commit is contained in:
王浩
2026-01-09 23:21:12 +08:00
parent 25a21f92be
commit 136e1344a0
2 changed files with 273 additions and 112 deletions

View File

@@ -62,9 +62,8 @@ signal chat_position_updated(stream: String, topic: String)
# 常量定义
# ============================================================================
# WebSocket 服务器 URL
# 添加 Socket.IO 握手参数EIO=4 表示 Engine.IO 版本transport=websocket
const WEBSOCKET_URL: String = "wss://whaletownend.xinghangee.icu/game/socket.io/?EIO=4&transport=websocket"
# WebSocket 服务器 URL(原生 WebSocket
const WEBSOCKET_URL: String = "wss://whaletownend.xinghangee.icu/game"
# 重连配置
const RECONNECT_MAX_ATTEMPTS: int = 5
@@ -102,9 +101,6 @@ const CHAT_ERROR_MESSAGES: Dictionary = {
# WebSocket 管理器
var _websocket_manager: WebSocketManager
# Socket.IO 客户端
var _socket_client: SocketIOClient
# 是否已登录
var _is_logged_in: bool = false
@@ -138,9 +134,6 @@ func _ready() -> void:
_websocket_manager = WebSocketManager.new()
add_child(_websocket_manager)
# 获取 Socket.IO 客户端引用
_socket_client = _websocket_manager.get_socket_client()
# 连接信号
_connect_signals()
@@ -191,7 +184,7 @@ func disconnect_from_chat_server() -> void:
# 发送登出消息
if _is_logged_in:
var logout_data := {"type": "logout"}
_socket_client.emit("logout", logout_data)
_websocket_manager.send_message(JSON.stringify(logout_data))
_is_logged_in = false
# 断开连接
@@ -245,8 +238,9 @@ func send_chat_message(content: String, scope: String = "local") -> void:
"scope": scope
}
# 发送消息
_socket_client.emit("chat", message_data)
# 发送消息JSON 字符串)
var json_string := JSON.stringify(message_data)
_websocket_manager.send_message(json_string)
# 记录发送时间
_record_message_timestamp()
@@ -261,6 +255,21 @@ func send_chat_message(content: String, scope: String = "local") -> void:
print("📤 发送聊天消息: ", content)
# 消息发送完成回调
func _on_chat_message_sent(request_id: String, success: bool, data: Dictionary, error_info: Dictionary) -> void:
if success:
print("✅ 消息发送成功: ", data)
var message_id: String = str(data.get("data", {}).get("id", ""))
var timestamp: float = Time.get_unix_time_from_system()
chat_message_sent.emit(message_id, timestamp)
EventSystem.emit_event(EventNames.CHAT_MESSAGE_SENT, {
"message_id": message_id,
"timestamp": timestamp
})
else:
print("❌ 消息发送失败: ", error_info)
_handle_error("SEND_FAILED", error_info.get("message", "发送失败"))
# 更新玩家位置
#
# 参数:
@@ -281,7 +290,10 @@ func update_player_position(x: float, y: float, map_id: String) -> void:
"mapId": map_id
}
_socket_client.emit("position", position_data)
# 发送消息JSON 字符串)
var json_string := JSON.stringify(position_data)
_websocket_manager.send_message(json_string)
print("📍 更新位置: (%.2f, %.2f) in %s" % [x, y, map_id])
# ============================================================================
@@ -435,28 +447,21 @@ func _on_history_loaded(messages: Array) -> void:
func _connect_signals() -> void:
# WebSocket 管理器信号
_websocket_manager.connection_state_changed.connect(_on_connection_state_changed)
_websocket_manager.data_received.connect(_on_data_received)
# Socket.IO 客户端信号
_socket_client.connected.connect(_on_socket_connected)
_socket_client.disconnected.connect(_on_socket_disconnected)
_socket_client.event_received.connect(_on_socket_event_received)
_socket_client.error_occurred.connect(_on_socket_error)
# ============================================================================
# 内部方法 - 连接状态处理
# ============================================================================
# Socket 连接成功
func _on_socket_connected() -> void:
print("✅ ChatManager: Socket 连接成功")
# 发送登录消息
_send_login_message()
# Socket 连接断开
func _on_socket_disconnected(_clean_close: bool) -> void:
print("🔌 ChatManager: Socket 连接断开")
_is_logged_in = false
# 发送登录消息
func _send_login_message() -> void:
print("📤 发送登录消息...")
var login_data := {
"type": "login",
"token": _game_token
}
var json_string := JSON.stringify(login_data)
_websocket_manager.send_message(json_string)
print(" Token: ", _game_token.left(20) + "..." if _game_token.length() > 20 else _game_token)
# 连接状态变化
func _on_connection_state_changed(state: int) -> void:
@@ -471,25 +476,45 @@ func _on_connection_state_changed(state: int) -> void:
"state": state
})
# 如果连接成功,发送登录消息
if state == 2: # CONNECTED
_send_login_message()
# ============================================================================
# 内部方法 - 消息处理
# ============================================================================
# Socket 事件接收
func _on_socket_event_received(event_name: String, data: Dictionary) -> void:
match event_name:
# WebSocket 数据接收
func _on_data_received(message: String) -> void:
# 解析 JSON 消息
var json := JSON.new()
var parse_result := json.parse(message)
if parse_result != OK:
print("❌ ChatManager: JSON 解析失败 - ", message)
return
var data: Dictionary = json.data
# 检查消息类型字段
var message_type: String = data.get("t", "")
match message_type:
"login_success":
_handle_login_success(data)
"login_error":
_handle_login_error(data)
"chat_sent":
_handle_chat_sent(data)
"chat_error":
_handle_chat_error(data)
"chat_render":
_handle_chat_render(data)
"position_updated":
_handle_position_updated(data)
"error":
_handle_error_response(data)
_:
print("⚠️ ChatManager: 未处理的事件 - ", event_name)
print("⚠️ ChatManager: 未处理的消息类型 - ", message_type)
print(" 消息内容: ", data)
# 处理登录成功
func _handle_login_success(data: Dictionary) -> void:
@@ -511,9 +536,23 @@ func _handle_login_success(data: Dictionary) -> void:
"current_map": _current_map
})
# 处理登录失败
func _handle_login_error(data: Dictionary) -> void:
var error_message: String = data.get("message", "登录失败")
print("❌ ChatManager: 登录失败 - ", error_message)
_is_logged_in = false
# 通过 EventSystem 广播错误Signal Up
EventSystem.emit_event(EventNames.CHAT_LOGIN_FAILED, {
"error_code": "LOGIN_FAILED",
"message": error_message
})
# 处理聊天消息发送成功
func _handle_chat_sent(data: Dictionary) -> void:
var message_id: String = data.get("messageId", "")
var message_id: String = str(data.get("messageId", ""))
var timestamp: float = data.get("timestamp", 0.0)
print("✅ 消息发送成功: ", message_id)
@@ -527,6 +566,18 @@ func _handle_chat_sent(data: Dictionary) -> void:
"timestamp": timestamp
})
# 处理聊天消息发送失败
func _handle_chat_error(data: Dictionary) -> void:
var error_message: String = data.get("message", "消息发送失败")
print("❌ ChatManager: 聊天错误 - ", error_message)
# 通过 EventSystem 广播错误Signal Up
EventSystem.emit_event(EventNames.CHAT_ERROR_OCCURRED, {
"error_code": "CHAT_SEND_FAILED",
"message": error_message
})
# 处理接收到的聊天消息
func _handle_chat_render(data: Dictionary) -> void:
var from_user: String = data.get("from", "")
@@ -571,14 +622,14 @@ func _handle_position_updated(data: Dictionary) -> void:
"topic": topic
})
# 处理错误响应
# 处理错误响应(如果需要)
func _handle_error_response(data: Dictionary) -> void:
var error_code: String = data.get("code", "")
var error_message: String = data.get("message", "")
_handle_error(error_code, error_message)
# 处理 Socket 错误
# 处理 Socket 错误(如果需要)
func _on_socket_error(error: String) -> void:
_handle_error("SOCKET_ERROR", error)
@@ -586,21 +637,6 @@ func _on_socket_error(error: String) -> void:
# 内部方法 - 工具函数
# ============================================================================
# 发送登录消息
func _send_login_message() -> void:
if _game_token.is_empty():
push_error("无法获取 access token请确保已登录")
_handle_error("AUTH_FAILED", "无法获取 access token请先登录")
return
var login_data := {
"type": "login",
"token": _game_token
}
_socket_client.emit("login", login_data)
print("📤 发送登录消息(使用 access token")
# 处理错误
func _handle_error(error_code: String, error_message: String) -> void:
print("❌ ChatManager 错误: [", error_code, "] ", error_message)