您的位置:首页 > 游戏 > 手游 > 网页制作个人主页素材_广州网络营销选择_网络优化行业的发展前景_长春关键词优化平台

网页制作个人主页素材_广州网络营销选择_网络优化行业的发展前景_长春关键词优化平台

2025/3/17 11:58:46 来源:https://blog.csdn.net/qq_32174013/article/details/146292538  浏览:    关键词:网页制作个人主页素材_广州网络营销选择_网络优化行业的发展前景_长春关键词优化平台
网页制作个人主页素材_广州网络营销选择_网络优化行业的发展前景_长春关键词优化平台

文章目录

    • 分析
    • 创建权威比赛
    • 控制台使用

【Unity网络同步框架 - Nakama研究(四)】

关于Nakama的源码问题,Nakama的源码官方是不建议修改的,不建议重构以添加新的功能,推荐使用嵌入式运行库,也就是使用lua,gotypescript进行扩展。

分析

  1. 扩展使用的语言中Go作为源码语言,能进行断点调试,而且性能高效,适合原生的服务端用户书写。相对应的,tslua就更加适合比如cocos creator或者使用lua进行Unity开发的人员书写,各有对应,遗憾的是目前官方对这两种语言都不支持断点调试,反馈
  2. 官方的案例中使用了ts进行扩展(在PiratePanic中能看到),在此之前,我们需要做一些工作,就是让Nakama能够识别你的扩展目录,在服务器的Docker配置中,扩展这一行就是你指定你的扩展的文件所存放的位置,比如我放两个lua文件ltest.luamain.lua进去,Nakama会自动读取对应位置的文件信息,然后打印出来载入lua,载入的顺序是按照你的文件名来排序的,日志里面也显示了你在里面注册了哪些rpc方法,你也能在客户端直接调用。

创建权威比赛

  • 权威比赛的一个关键点就是房间内没人也依旧会存在,而且可以自定义房间内的比赛逻辑,包括如何开始如何结束等等。逻辑也很简单,就是那几个关键的函数方法:match_join,match_leave,match_loop(主要是这三个),下面是我写着测试的代码:main.lualtest.lua
local nk = require("nakama")
nk.logger_info("Lua模块进入------")-- 创建比赛
local state = {label = "比赛一"
}
local match_id = nk.match_create("ltest", state)
local state_2 = {label = "比赛二"
}
local match_id_2 = nk.match_create("ltest", state_2)
local state_3 = {label = "比赛三"
}
local match_id_3 = nk.match_create("ltest", state_3)------------------------------------function healthcheck_rpc(content, payload)nk.logger_info("Healthcheck RPC called")return nk.json_encode({["success"] = true})
endfunction getmatchlist_rpc(content, payload)-- 列出当前所有比赛local limit = 10local authoritative = falselocal label = nillocal min_size = 1local max_size = 10local matches = nk.match_list(limit, authoritative, label, min_size, max_size)-- 构建返回的 JSON 结构local matchList = {}for _, m in ipairs(matches) dotable.insert(matchList, {match_id = m.match_id,size = m.size,max_size = m.max_size,authoritative = m.is_authoritative})end-- 返回 JSON 结构return nk.json_encode({ matches = matchList })
endnk.register_rpc(healthcheck_rpc, "healthcheck_lua")
nk.register_rpc(getmatchlist_rpc, "getmatchlist_lua")
local M = {}
local nk = require("nakama")function M.match_init(context, setupstate)local gamestate = {presences = {},name = "",min_size = 1,max_size = 10,is_authoritative = false,label = setupstate.label}-- 设置 tick 率local tickrate = 30-- 设置比赛标签local label = gamestate.label or ""nk.logger_warn("match_init")return gamestate, tickrate, label
endfunction M.match_join_attempt(context, dispatcher, tick, state, presence, metadata)local acceptuser = truenk.logger_warn("match_join_attempt")return state, acceptuser
endfunction M.match_join(context, dispatcher, tick, state, presences)nk.logger_warn("match_join")-- 先添加新玩家到状态for _, presence in ipairs(presences) dostate.presences[presence.session_id] = presenceend-- 发送玩家加入通知for _, presence in ipairs(presences) do-- 构造加入消息local join_message = {op = 10,  -- 新操作码表示玩家加入type = "PLAYER_JOINED",timestamp = os.time(),data = {user = {id = presence.user_id,name = presence.username},session = presence.session_id}}-- 构建收件人列表(排除自己)local recipients = {}for _, p in pairs(state.presences) doif p.session_id ~= presence.session_id thentable.insert(recipients, p)endend-- 发送加入广播if #recipients > 0 thendispatcher.broadcast_message(10, nk.json_encode(join_message), recipients)nk.logger_info(string.format("Player %s(%s) joined the match", presence.user_id, presence.username))end-- 给新玩家发送现有玩家列表local existing_players = {}for _, p in pairs(state.presences) doif p.session_id ~= presence.session_id thentable.insert(existing_players, {user_id = p.user_id,username = p.username,session_id = p.session_id})endendif #existing_players > 0 thenlocal existing_msg = {op = 11,type = "EXISTING_PLAYERS",data = existing_players}dispatcher.broadcast_message(11, nk.json_encode(existing_msg), { presence })endend-- 原有存储数据逻辑(保持兼容)for _, presence in pairs(state.presences) dolocal storageObjectId = {{ collection = "test", key = "key1", user_id = presence.user_id }}local storageObject = nk.storage_read(storageObjectId)if storageObject thenlocal message = {op = 99,data = storageObject}-- 使用新通知系统dispatcher.broadcast_message(99, nk.json_encode(message))elsenk.logger_warn("storageObject为空,查询的user id为" .. presence.user_id)endendreturn state
end-- presences表示离开的人数
function M.match_leave(context, dispatcher, tick, state, presences)-- 遍历所有离开的玩家for _, presence in ipairs(presences) do-- 构造离开消息local leave_message = {UserId = presence.user_id,UserName = presence.username,SessionId = presence.session_id,Reason = "player_left"}-- 构建收件人列表(排除离开的玩家)local recipients = {}for _, p in pairs(state.presences) doif p.session_id ~= presence.session_id thentable.insert(recipients, p)endend-- 发送离开通知(使用op_code 6表示玩家离开)if #recipients > 0 thendispatcher.broadcast_message(6, nk.json_encode(leave_message), recipients)nk.logger_info(string.format("Player %s(%s) left the match", presence.user_id, presence.username))end-- 从状态中移除玩家state.presences[presence.session_id] = nilendreturn state
end-- 处理比赛人员交互操作
function M.match_loop(context, dispatcher, tick, state, messages)if(messages ~= nil) thenfor _, m in ipairs(messages) dolocal recipients = {}for _, p in pairs(state.presences) doif p.user_id ~= m.sender.user_id thentable.insert(recipients, p)endendif #recipients > 0 thenif(m ~= nil and m.op_code ~= nil) thendispatcher.broadcast_message(m.op_code, m.data, recipients)endendendendreturn state
end-- 用于在服务器关闭时,优雅地处理比赛状态,确保比赛能够正确结束并通知客户端
function M.match_terminate(context, dispatcher, tick, state, grace_seconds)local message = "Server shutting down in " .. grace_seconds .. " seconds"dispatcher.broadcast_message(2, message)return nil
end-- 用于在用户正式加入比赛之前,提前预留位置或进行一些预处理
function M.match_signal(context, dispatcher, tick, state, data)return state, "signal received: " .. data
endreturn M

对了,还有一点麻烦的是,vscode里面没有代码提示,可以搞个前人写好的库,我找了下,在github上能找到地址,能补充一下缺失的提示框(但是错误提示依旧没有)

控制台使用

  • 控制台如果你想要其他的图形化的比如Grafana 啥的,也能自己搭建,不过目前我看这个控制大多数都能满足,包括查看用户,查看聊天信息,查看比赛(房间)信息,然后主动调用接口,还是挺方便的,这个没什么好讲的控制台

结语,Nakama相关的一些使用就到这,再深的讲就是一些服务器的布置,负载均衡,集群啥的了(集群需要Nakama的企业版),Nakama本身自带的一些功能比如排行榜,好友群组,连接facebook,x啥的我都没试。再深入研究要等下次有机会了

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com