公会系统:network_manager.lua
```lua
-- modules/network_manager.lua
-- 网络管理器模块,支持proto协议、重连机制、心跳保活
local utils = require("core.utils")
local class = require("core.class")
local event = require("core.event")
local moduleBase = require("core.module")
local NetworkManager = moduleBase.Module:extend("NetworkManager")
-- 错误码定义
local ErrorCode = {
SUCCESS = 0,
NETWORK_ERROR = 1001,
TIMEOUT = 1002,
SERVER_ERROR = 1003,
NOT_LOGIN = 1004,
INVALID_PARAM = 1005
}
-- 连接状态
local ConnectionState = {
DISCONNECTED = 0,
CONNECTING = 1,
CONNECTED = 2,
RECONNECTING = 3
}
function NetworkManager:ctor(name)
NetworkManager.super.ctor(self, name)
self.connectionState = ConnectionState.DISCONNECTED
self.serverUrl = ""
self.serverPort = 0
self.socket = nil
self.webSocket = nil
-- 消息处理
self.messageHandlers = {}
self.requestCallbacks = {}
self.requestId = 0
-- 重连机制
self.reconnectInterval = 3 -- 重连间隔(秒)
self.maxReconnectAttempts = 5
self.reconnectAttempts = 0
self.autoReconnect = true
-- 心跳机制
self.heartbeatInterval = 30 -- 心跳间隔(秒)
self.heartbeatTimer = nil
self.lastHeartbeatTime = 0
-- 超时处理
self.requestTimeout = 10 -- 请求超时时间(秒)
self.timeoutTimers = {}
end
function NetworkManager:initialize()
utils.print("初始化网络管理器...")
-- 初始化C#网络组件
self:InitNetworkComponent()
-- 注册消息处理器
self:RegisterDefaultHandlers()
NetworkManager.super.initialize(self)
end
function NetworkManager:InitNetworkComponent()
-- 获取或创建C#网络管理器
if CS.NetworkManager.Instance == nil then
local go = CS.UnityEngine.GameObject("NetworkManager")
CS.UnityEngine.Object.DontDestroyOnLoad(go)
go:AddComponent(typeof(CS.NetworkManager))
end
-- 绑定回调
CS.NetworkManager.Instance.onConnected = function()
self:OnConnected()
end
CS.NetworkManager.Instance.onDisconnected = function()
self:OnDisconnected()
end
CS.NetworkManager.Instance.onMessage = function(data)
self:OnMessage(data)
end
CS.NetworkManager.Instance.onError = function(error)
self:OnError(error)
end
end
function NetworkManager:RegisterDefaultHandlers()
-- 注册服务器推送消息处理器
self:RegisterHandler("guild.NewChatPush", function(push)
self:OnNewChatPush(push)
end)
self:RegisterHandler("guild.GuildMember", function(push)
self:OnMemberUpdate(push)
end)
end
-- 连接服务器
function NetworkManager:Connect(serverUrl, serverPort)
if self.connectionState == ConnectionState.CONNECTED then
utils.print("已经连接到服务器")
return
end
self.serverUrl = serverUrl
self.serverPort = serverPort
self.connectionState = ConnectionState.CONNECTING
utils.print("正在连接服务器: " .. serverUrl .. ":" .. serverPort)
-- 调用C#网络组件连接
CS.NetworkManager.Instance:Connect(serverUrl, serverPort)
-- 派发连接中事件
event.emit("NETWORK_CONNECTING")
end
-- 断开连接
function NetworkManager:Disconnect()
self.autoReconnect = false
if self.socket then
self.socket:Close()
self.socket = nil
end
if self.webSocket then
self.webSocket:Close()
self.webSocket = nil
end
self.connectionState = ConnectionState.DISCONNECTED
self:StopHeartbeat()
utils.print("已断开与服务器的连接")
event.emit("NETWORK_DISCONNECTED")
end
-- 发送消息(异步)
function NetworkManager:SendRequest(serviceName, requestMessage, callback)
if self.connectionState ~= ConnectionState.CONNECTED then
utils.print("未连接到服务器,无法发送消息")
if callback then
callback(ErrorCode.NETWORK_ERROR, "未连接到服务器")
end
return
end
-- 生成请求ID
self.requestId = self.requestId + 1
local requestId = self.requestId
-- 注册回调
if callback then
self.requestCallbacks[requestId] = callback
-- 设置超时定时器
self:SetRequestTimeout(requestId)
end
-- 序列化消息
local request = {
request_id = requestId,
service = serviceName,
data = requestMessage
}
local jsonData = CS.JsonUtility.ToJson(request)
-- 发送数据
CS.NetworkManager.Instance:Send(jsonData)
utils.print("发送请求: " .. serviceName .. " (request_id: " .. requestId .. ")")
end
-- 同步发送消息(使用协程)
function NetworkManager:SendRequestSync(serviceName, requestMessage)
return coroutine.yield(function(callback)
self:SendRequest(serviceName, requestMessage, callback)
end)
end
-- 注册消息处理器
function NetworkManager:RegisterHandler(messageType, handler)
if not self.messageHandlers[messageType] then
self.messageHandlers[messageType] = {}
end
table.insert(self.messageHandlers[messageType], handler)
end
-- 移除消息处理器
function NetworkManager:UnregisterHandler(messageType, handler)
if not self.messageHandlers[messageType] then
return
end
for i = #self.messageHandlers[messageType], 1, -1 do
if self.messageHandlers[messageType][i] == handler then
table.remove(self.messageHandlers[messageType], i)
end
end
end
-- 连接成功回调
function NetworkManager:OnConnected()
self.connectionState = ConnectionState.CONNECTED
self.reconnectAttempts = 0
utils.print("连接服务器成功")
-- 启动心跳
self:StartHeartbeat()
-- 派发连接成功事件
event.emit("NETWORK_CONNECTED")
end
-- 连接断开回调
function NetworkManager:OnDisconnected()
self.connectionState = ConnectionState.DISCONNECTED
utils.print("与服务器的连接断开")
-- 停止心跳
self:StopHeartbeat()
-- 清理所有请求回调
for requestId, callback in pairs(self.requestCallbacks) do
callback(ErrorCode.NETWORK_ERROR, "连接断开")
end
self.requestCallbacks = {}
-- 派发断开连接事件
event.emit("NETWORK_DISCONNECTED")
-- 自动重连
if self.autoReconnect then
self:TryReconnect()
end
end
-- 收到消息回调
function NetworkManager:OnMessage(data)
-- 解析JSON数据
local response = CS.JsonUtility.FromJson(data)
if not response then
utils.print("消息解析失败")
return
end
-- 检查是否是响应消息
if response.request_id and response.result ~= nil then
self:HandleResponse(response)
else
-- 处理服务器推送消息
self:HandlePush(response)
end
end
-- 处理响应消息
function NetworkManager:HandleResponse(response)
local requestId = response.request_id
local result = response.result
local message = response.message or ""
local data = response.data
-- 清除超时定时器
self:ClearRequestTimeout(requestId)
-- 执行回调
local callback = self.requestCallbacks[requestId]
if callback then
callback(result, message, data)
self.requestCallbacks[requestId] = nil
end
utils.print("收到响应: request_id=" .. requestId .. ", result=" .. result)
end
-- 处理推送消息
function NetworkManager:HandlePush(push)
local messageType = push.message_type or push.push_data
-- 调用注册的处理器
if self.messageHandlers[messageType] then
for _, handler in ipairs(self.messageHandlers[messageType]) do
handler(push)
end
end
-- 派发通用推送事件
event.emit("NETWORK_PUSH", messageType, push)
end
-- 错误回调
function NetworkManager:OnError(error)
utils.print("网络错误: " .. error)
event.emit("NETWORK_ERROR", error)
end
-- 新消息推送处理
function NetworkManager:OnNewChatPush(push)
local chatMessage = push.new_chat or push.chat_message
if chatMessage then
event.emit("CHAT_NEW_MESSAGE", chatMessage)
end
end
-- 成员更新推送处理
function NetworkManager:OnMemberUpdate(push)
local member = push.member_update or push
if member then
event.emit("GUILD_MEMBER_UPDATE", member)
end
end
-- 尝试重连
function NetworkManager:TryReconnect()
if self.reconnectAttempts >= self.maxReconnectAttempts then
utils.print("达到最大重连次数,停止重连")
event.emit("NETWORK_RECONNECT_FAILED")
return
end
self.reconnectAttempts = self.reconnectAttempts + 1
self.connectionState = ConnectionState.RECONNECTING
utils.print("尝试重连 (" .. self.reconnectAttempts .. "/" .. self.maxReconnectAttempts .. ")")
event.emit("NETWORK_RECONNECTING", self.reconnectAttempts)
-- 延迟重连
CS.CoroutineUtility.StartCoroutine(function()
CS.UnityEngine.Yield(CS.UnityEngine.WaitForSeconds(self.reconnectInterval))
self:Connect(self.serverUrl, self.serverPort)
end)
end
-- 启动心跳
function NetworkManager:StartHeartbeat()
self:StopHeartbeat()
self.heartbeatTimer = CS.CoroutineUtility.StartCoroutine(function()
while self.connectionState == ConnectionState.CONNECTED do
CS.UnityEngine.Yield(CS.UnityEngine.WaitForSeconds(self.heartbeatInterval))
self:SendHeartbeat()
end
end)
end
-- 停止心跳
function NetworkManager:StopHeartbeat()
if self.heartbeatTimer then
CS.CoroutineUtility.StopCoroutine(self.heartbeatTimer)
self.heartbeatTimer = nil
end
end
-- 发送心跳
function NetworkManager:SendHeartbeat()
local currentTime = CS.UnityEngine.Time.time
-- 构造心跳包
local heartbeat = {
timestamp = currentTime,
client_time = os.time()
}
CS.NetworkManager.Instance:SendHeartbeat(CS.JsonUtility.ToJson(heartbeat))
self.lastHeartbeatTime = currentTime
end
-- 设置请求超时
function NetworkManager:SetRequestTimeout(requestId)
self.timeoutTimers[requestId] = CS.CoroutineUtility.StartCoroutine(function()
CS.UnityEngine.Yield(CS.UnityEngine.WaitForSeconds(self.requestTimeout))
if self.requestCallbacks[requestId] then
local callback = self.requestCallbacks[requestId]
self.requestCallbacks[requestId] = nil
callback(ErrorCode.TIMEOUT, "请求超时")
utils.print("请求超时: " .. requestId)
end
self.timeoutTimers[requestId] = nil
end)
end
-- 清除请求超时
function NetworkManager:ClearRequestTimeout(requestId)
if self.timeoutTimers[requestId] then
CS.CoroutineUtility.StopCoroutine(self.timeoutTimers[requestId])
self.timeoutTimers[requestId] = nil
end
end
-- 获取连接状态
function NetworkManager:GetConnectionState()
return self.connectionState
end
-- 判断是否已连接
function NetworkManager:IsConnected()
return self.connectionState == ConnectionState.CONNECTED
end
-- 更新方法
function NetworkManager:update(deltaTime)
-- 检查心跳超时
if self.connectionState == ConnectionState.CONNECTED then
local currentTime = CS.UnityEngine.Time.time
if currentTime - self.lastHeartbeatTime > self.heartbeatInterval * 2 then
utils.print("心跳超时,断开连接")
self:Disconnect()
end
end
end
function NetworkManager:destroy()
self:Disconnect()
self.autoReconnect = false
NetworkManager.super.destroy(self)
end
-- 导出常量
NetworkManager.ErrorCode = ErrorCode
NetworkManager.ConnectionState = ConnectionState
return NetworkManager
```