protobufUtil.lua 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. local skynet = require "skynet"
  2. local lfs = require "lfs"
  3. local HANDLE_PROTO
  4. local root = {}
  5. -- 解析协议名字
  6. local function l_get_cmd(name)
  7. local pos = string.find(name, "_", 1, true)
  8. if not pos then
  9. return nil
  10. end
  11. local protoKey = string.sub(name, 1, pos - 1)
  12. local protoName = string.sub(name, pos + 1, #name)
  13. return protoKey, protoName
  14. end
  15. -- 获取rpc文件
  16. local function l_get_rpc(protoKey)
  17. local fileName = "rpc_" .. protoKey
  18. local fullName = "rpc." .. fileName
  19. return fileName, require(fullName)
  20. end
  21. -- 处理协议
  22. function root.handle_proto(protoName, uid, args)
  23. -- 解析出协议名字
  24. local index = string.find(protoName, "%.")
  25. protoName = string.sub(protoName, index + 1, string.len(protoName))
  26. -- 名字格式不对
  27. local protoKey, funcName = l_get_cmd(protoName)
  28. if not protoKey or not funcName then
  29. skynet.error(string.format("handle proto:%s fail", protoName))
  30. return
  31. end
  32. -- 根据proto_key获取对应的rpc文件
  33. local fileName, rpcFile = l_get_rpc(protoKey)
  34. if not rpcFile then
  35. skynet.error(string.format("get rpc file:%s fail, protoName:%s", "rpc_" .. protoKey, protoName))
  36. return
  37. end
  38. -- 执行函数
  39. local func = rpcFile[funcName]
  40. if not func then
  41. skynet.error(string.format("rpcFile:%s have no func:%s", fileName, funcName))
  42. return
  43. end
  44. local ok, rs =
  45. xpcall(
  46. func,
  47. function()
  48. skynet.error(debug.traceback())
  49. end,
  50. uid,
  51. args
  52. )
  53. if not ok then
  54. skynet.error(string.format("rpcFile:%s, do func:%s, args:%s fail", fileName, funcName, tostring(args)))
  55. return
  56. end
  57. return rs
  58. end
  59. -- 获取http服的协议
  60. function root.get_http_protos()
  61. local ret = {}
  62. local pb_path = "./proto/pb/"
  63. for file in lfs.dir(pb_path) do
  64. if string.find(file, "http") or file == "msg.pb" then
  65. table.insert(ret, file)
  66. end
  67. end
  68. return pb_path, ret
  69. end
  70. -- 获取game服的协议
  71. function root.get_game_protos()
  72. local list = {}
  73. local path = "./proto/pb/"
  74. for file in lfs.dir(path) do
  75. if not (file == "." or file == "..") then
  76. if not string.find(file, "http") then
  77. table.insert(list, file)
  78. end
  79. end
  80. end
  81. return path, list
  82. end
  83. -- 初始化协议句柄
  84. function root.init_proto_handle()
  85. local ok, handle = pcall(skynet.call, ".proto_mgr", "lua", "get_proto_handle")
  86. if not ok or not handle then
  87. skynet.error("解析获取协议服务失败...")
  88. return false
  89. end
  90. HANDLE_PROTO = handle
  91. return true
  92. end
  93. -- 解析protobuf协议
  94. function root.parse_protobuf_data(msg)
  95. local ok, body = pcall(skynet.call, HANDLE_PROTO, "lua", "decode", "msg.proto_msg", msg)
  96. if not ok or not body then
  97. skynet.error("解析msg协议包失败...")
  98. return false
  99. end
  100. local protoName = body.protoName
  101. local proto_data = body.proto_data
  102. local session = body.session
  103. if not protoName or not proto_data then
  104. skynet.error("msg协议包格式不正确...")
  105. return false
  106. end
  107. local ok, args = pcall(skynet.call, HANDLE_PROTO, "lua", "decode", protoName, proto_data)
  108. if not ok or not args then
  109. skynet.error(string.format("解析协议[%s]失败...", protoName))
  110. return false
  111. end
  112. local response
  113. local rsp_proto_name = string.gsub(protoName, "_req_", "_rsp_", 1)
  114. if not rsp_proto_name then
  115. skynet.error(string.format("协议[%s]名称不正确, args:%s...", protoName, tostring(args)))
  116. return false
  117. end
  118. local rsp_proto_func = function(name, res)
  119. local ok, body = pcall(skynet.call, HANDLE_PROTO, "lua", "encode", name, res)
  120. if not ok or not body then
  121. skynet.error(string.format("编码回应协议[%s]失败...", name))
  122. return
  123. end
  124. local ok, new_body =
  125. pcall(
  126. skynet.call,
  127. HANDLE_PROTO,
  128. "lua",
  129. "encode",
  130. "msg.proto_msg",
  131. {
  132. protoName = name,
  133. proto_data = body,
  134. session = session,
  135. timestamp = os.time()
  136. }
  137. )
  138. if not ok or not new_body then
  139. skynet.error(string.format("编码回应协议[%s][msg]失败...", name))
  140. return
  141. end
  142. return new_body
  143. end
  144. response = {
  145. rsp_proto_name = rsp_proto_name,
  146. rsp_proto_func = rsp_proto_func
  147. }
  148. return true, protoName, args, response, session
  149. end
  150. -- 打包推送的消息
  151. function root.pack_push_msg(name, msg)
  152. local ok, body = pcall(skynet.call, HANDLE_PROTO, "lua", "encode", name, msg)
  153. if not ok or not body then
  154. skynet.error(string.format("编码推送协议[%s]失败...", name))
  155. return
  156. end
  157. local ok, new_body =
  158. pcall(
  159. skynet.call,
  160. HANDLE_PROTO,
  161. "lua",
  162. "encode",
  163. "msg.proto_msg",
  164. {
  165. protoName = name,
  166. proto_data = body,
  167. timestamp = os.time()
  168. }
  169. )
  170. if not ok or not new_body then
  171. skynet.error(string.format("编码推送协议[%s][msg]失败...", name))
  172. return
  173. end
  174. return new_body
  175. end
  176. -- 打包回应的消息
  177. function root.pack_response_msg(req_proto_name, rsp_proto_data, session)
  178. local rsp_proto_name = string.gsub(req_proto_name, "_req_", "_rsp_", 1)
  179. if not rsp_proto_name then
  180. skynet.error(string.format("请求协议[%s]名称不正确", req_proto_name))
  181. return
  182. end
  183. local ok, body = pcall(skynet.call, HANDLE_PROTO, "lua", "encode", rsp_proto_name, rsp_proto_data)
  184. if not ok or not body then
  185. skynet.error(string.format("编码回应协议[%s]失败...", rsp_proto_name))
  186. return
  187. end
  188. local ok, new_body =
  189. pcall(
  190. skynet.call,
  191. HANDLE_PROTO,
  192. "lua",
  193. "encode",
  194. "msg.proto_msg",
  195. {
  196. protoName = rsp_proto_name,
  197. proto_data = body,
  198. session = session,
  199. timestamp = os.time()
  200. }
  201. )
  202. if not ok or not new_body then
  203. skynet.error(string.format("编码回应协议[%s][msg]失败...", rsp_proto_name))
  204. return
  205. end
  206. return new_body
  207. end
  208. return root