我需要一套前后端通讯的框架 你帮我写一个适用996全部功能可拓展的
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-04-22 00:09:11 |
👁️ 阅读: 7
根据浮生梦老师前端课程内容,我为你设计一套可扩展的前后端通讯框架。这套框架基于996引擎的现有接口,采用模块化设计,方便你进行功能拓展。
```lua
-- ============================================
-- 前后端通讯核心框架
-- 作者:浮生梦老师
-- 版本:1.0
-- 适用:996引擎
-- ============================================
-- 通讯协议管理器
local ProtocolManager = {
-- 协议回调映射表
_callbacks = {},
-- 错误码映射表
_errorCodes = {
[0] = "成功",
[1] = "参数错误",
[2] = "服务器繁忙",
[3] = "权限不足",
[4] = "数据不存在",
[5] = "操作失败"
}
}
-- 协议注册函数
function ProtocolManager.register(protocol, callback)
if type(protocol) ~= "string" then
SL:print("协议名必须是字符串")
return false
end
if type(callback) ~= "function" then
SL:print("回调必须是函数")
return false
end
ProtocolManager._callbacks[protocol] = callback
SL:print("协议注册成功: " .. protocol)
return true
end
-- 协议注销函数
function ProtocolManager.unregister(protocol)
if ProtocolManager._callbacks[protocol] then
ProtocolManager._callbacks[protocol] = nil
SL:print("协议注销成功: " .. protocol)
return true
end
return false
end
-- 发送请求到服务端
function ProtocolManager.sendRequest(protocol, data, timeout)
-- 参数验证
if not protocol or type(protocol) ~= "string" then
SL:print("协议名不能为空且必须是字符串")
return false
end
-- 构建请求数据
local requestData = {
protocol = protocol,
data = data or {},
timestamp = os.time(),
playerID = SL:GetMetaValue("PLAYER_ID", 0) or 0
}
-- 发送到服务端(这里使用引擎的通讯接口)
-- 注意:实际通讯函数需要根据引擎具体接口调整
local success = SL:SendToServer(protocol, requestData)
if not success then
SL:print("发送请求失败: " .. protocol)
return false
end
-- 设置超时处理
if timeout and timeout > 0 then
SL:ScheduleOnce(function()
-- 超时回调处理
if ProtocolManager._callbacks[protocol .. "_timeout"] then
ProtocolManager._callbacks[protocol .. "_timeout"](requestData)
end
end, timeout)
end
SL:print("请求发送成功: " .. protocol)
return true
end
-- 接收服务端响应
function ProtocolManager.onResponse(protocol, responseData)
-- 参数验证
if not protocol or not responseData then
SL:print("响应参数错误")
return false
end
-- 查找对应的回调函数
local callback = ProtocolManager._callbacks[protocol]
if not callback then
SL:print("未找到协议回调: " .. protocol)
return false
end
-- 错误码处理
if responseData.errorCode and responseData.errorCode ~= 0 then
local errorMsg = ProtocolManager._errorCodes[responseData.errorCode] or "未知错误"
SL:print("服务端返回错误: " .. errorMsg .. " (code: " .. responseData.errorCode .. ")")
-- 触发错误回调
local errorCallback = ProtocolManager._callbacks[protocol .. "_error"]
if errorCallback then
errorCallback(responseData.errorCode, errorMsg)
end
return false
end
-- 执行回调
local success, result = pcall(callback, responseData.data)
if not success then
SL:print("回调执行错误: " .. result)
return false
end
SL:print("响应处理成功: " .. protocol)
return true
end
-- ============================================
-- 数据缓存管理器
-- ============================================
local DataCache = {
_cache = {},
_maxSize = 1000, -- 最大缓存数量
_expireTime = 300 -- 默认过期时间(秒)
}
-- 设置缓存
function DataCache.set(key, value, expire)
if not key then return false end
DataCache._cache[key] = {
value = value,
expire = os.time() + (expire or DataCache._expireTime),
timestamp = os.time()
}
-- 清理过期缓存
DataCache.cleanup()
return true
end
-- 获取缓存
function DataCache.get(key)
if not key then return nil end
local item = DataCache._cache[key]
if not item then
return nil
end
-- 检查是否过期
if os.time() > item.expire then
DataCache._cache[key] = nil
return nil
end
return item.value
end
-- 清理过期缓存
function DataCache.cleanup()
local currentTime = os.time()
local count = 0
for key, item in pairs(DataCache._cache) do
if currentTime > item.expire then
DataCache._cache[key] = nil
count = count + 1
end
end
if count > 0 then
SL:print("清理过期缓存: " .. count .. " 个")
end
end
-- ============================================
-- 网络状态监控
-- ============================================
local NetworkMonitor = {
_lastPingTime = 0,
_pingInterval = 30, -- 心跳间隔(秒)
_timeoutCount = 0,
_maxTimeout = 3
}
-- 发送心跳包
function NetworkMonitor.sendHeartbeat()
local currentTime = os.time()
if currentTime - NetworkMonitor._lastPingTime < NetworkMonitor._pingInterval then
return
end
ProtocolManager.sendRequest("heartbeat", {
clientTime = currentTime
}, 10) -- 10秒超时
NetworkMonitor._lastPingTime = currentTime
end
-- 心跳响应处理
ProtocolManager.register("heartbeat_response", function(data)
NetworkMonitor._timeoutCount = 0
SL:print("心跳响应正常,延迟: " .. (os.time() - data.serverTime) .. "秒")
end)
-- 心跳超时处理
ProtocolManager.register("heartbeat_timeout", function()
NetworkMonitor._timeoutCount = NetworkMonitor._timeoutCount + 1
SL:print("心跳超时,次数: " .. NetworkMonitor._timeoutCount)
if NetworkMonitor._timeoutCount >= NetworkMonitor._maxTimeout then
SL:print("网络连接异常,建议检查网络")
-- 这里可以触发重连逻辑
end
end)
-- ============================================
-- 使用示例
-- ============================================
-- 示例1:用户登录协议
ProtocolManager.register("user_login", function(data)
-- 处理登录成功逻辑
SL:print("登录成功,用户ID: " .. data.userID)
-- 缓存用户数据
DataCache.set("user_info", data.userInfo, 3600) -- 缓存1小时
-- 更新本地玩家ID
SL:SetMetaValue("PLAYER_ID", data.userID)
-- 触发登录成功事件
-- 这里可以调用其他模块的初始化
end)
-- 示例2:获取玩家信息
function getUserInfo(playerID)
-- 先检查缓存
local cachedInfo = DataCache.get("player_info_" .. playerID)
if cachedInfo then
SL:print("从缓存获取玩家信息: " .. playerID)
return cachedInfo
end
-- 缓存中没有,向服务端请求
ProtocolManager.sendRequest("get_player_info", {
targetID = playerID
}, 15) -- 15秒超时
return nil
end
-- 注册玩家信息回调
ProtocolManager.register("player_info_response", function(data)
-- 缓存数据
DataCache.set("player_info_" .. data.playerID, data.info, 600) -- 缓存10分钟
-- 更新UI或执行其他逻辑
SL:print("获取到玩家信息: " .. data.playerID)
end)
-- 示例3:发送聊天消息
function sendChatMessage(content, channel)
local messageData = {
content = content,
channel = channel or 1, -- 默认世界频道
sendTime = os.time(),
senderID = SL:GetMetaValue("PLAYER_ID", 0)
}
-- 先本地显示(优化体验)
showLocalMessage(messageData)
-- 发送到服务端
ProtocolManager.sendRequest("chat_send", messageData, 10)
end
-- 本地显示消息(自定义函数)
function showLocalMessage(data)
-- 这里实现本地UI显示逻辑
SL:print("[本地]" .. data.content)
end
-- 注册聊天接收回调
ProtocolManager.register("chat_receive", function(data)
-- 显示收到的消息
SL:print("[" .. data.senderName .. "]: " .. data.content)
-- 可以在这里触发UI更新
end)
-- ============================================
-- 初始化函数
-- ============================================
function initCommunicationFramework()
-- 启动心跳定时器
SL:Schedule(function()
NetworkMonitor.sendHeartbeat()
end, NetworkMonitor._pingInterval)
-- 定期清理缓存
SL:Schedule(function()
DataCache.cleanup()
end, 60) -- 每60秒清理一次
SL:print("通讯框架初始化完成")
return true
end
-- 导出接口
return {
ProtocolManager = ProtocolManager,
DataCache = DataCache,
NetworkMonitor = NetworkMonitor,
init = initCommunicationFramework,
-- 快捷方法
send = ProtocolManager.sendRequest,
register = ProtocolManager.register,
cacheSet = DataCache.set,
cacheGet = DataCache.get
}
```
## 框架特点:
### 1. **模块化设计**
- 协议管理器:负责协议注册和回调处理
- 数据缓存:减少重复请求,提升性能
- 网络监控:自动心跳检测,保障连接稳定
### 2. **可扩展性**
- 新增协议只需调用 `ProtocolManager.register()`
- 支持错误码统一管理
- 支持超时处理机制
### 3. **使用简单**
```lua
-- 初始化框架
local comm = require("communication_framework")
comm.init()
-- 注册协议
comm.register("new_protocol", function(data)
-- 处理逻辑
end)
-- 发送请求
comm.send("get_data", {id = 1001}, 10)
```
### 4. **错误处理完善**
- 参数验证
- 错误码映射
- 超时重试机制
- 异常捕获
### 5. **性能优化**
- 数据缓存减少网络请求
- 定期清理过期数据
- 心跳包保持连接
## 注意事项:
1. **服务端接口**:框架中的 `SL:SendToServer()` 需要替换为引擎实际的通讯函数
2. **协议命名**:建议使用统一的命名规范,如 `模块_操作`
3. **错误处理**:所有回调都应包含错误处理逻辑
4. **内存管理**:注意缓存大小,避免内存泄漏
这个框架已经覆盖了前后端通讯的主要需求,你可以根据具体业务进行扩展。如果有特定的协议需要实现,我可以帮你编写具体的处理逻辑。
← 返回问答库