mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Use msgpack for API
This commit is contained in:
parent
3d328c1d42
commit
bda2af3dfb
12 changed files with 264 additions and 172 deletions
|
|
@ -1,5 +1,6 @@
|
|||
local HttpService = game:GetService("HttpService")
|
||||
local JSON5Decoder = require(script.Parent.Parent.json5.JSON5Decoder)
|
||||
|
||||
local msgpack = require(script.Parent.Parent.msgpack)
|
||||
|
||||
local stringTemplate = [[
|
||||
Http.Response {
|
||||
|
|
@ -29,13 +30,11 @@ function Response:isSuccess()
|
|||
end
|
||||
|
||||
function Response:json()
|
||||
-- Try fast native decode first, fallback to JSON5 for NaN/Infinity
|
||||
local success, result = pcall(HttpService.JSONDecode, HttpService, self.body)
|
||||
if success then
|
||||
return result
|
||||
end
|
||||
print("[HTTP Response:json()] Native decode failed, using JSON5 for size:", #self.body)
|
||||
return JSON5Decoder.Decode(self.body)
|
||||
return HttpService:JSONDecode(self.body)
|
||||
end
|
||||
|
||||
function Response:msgpack()
|
||||
return msgpack.decode(self.body)
|
||||
end
|
||||
|
||||
return Response
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
local HttpService = game:GetService("HttpService")
|
||||
|
||||
local Promise = require(script.Parent.Promise)
|
||||
local Log = require(script.Parent.Log)
|
||||
local JSON5Decoder = require(script.Parent.json5.JSON5Decoder)
|
||||
local JSONEncoder = require(script.Parent.json5.JSONEncoder)
|
||||
local msgpack = require(script.Parent.msgpack)
|
||||
local Promise = require(script.Parent.Promise)
|
||||
|
||||
local HttpError = require(script.Error)
|
||||
local HttpResponse = require(script.Response)
|
||||
|
|
@ -63,17 +62,19 @@ function Http.post(url, body)
|
|||
end
|
||||
|
||||
function Http.jsonEncode(object)
|
||||
return JSONEncoder.Compact5(object)
|
||||
return HttpService:JSONEncode(object)
|
||||
end
|
||||
|
||||
function Http.jsonDecode(source)
|
||||
-- Try fast native decode first, fallback to JSON5 for NaN/Infinity
|
||||
local success, result = pcall(HttpService.JSONDecode, HttpService, source)
|
||||
if success then
|
||||
return result
|
||||
end
|
||||
print("[Http.jsonDecode] Native decode failed, using JSON5 for size:", #source)
|
||||
return JSON5Decoder.Decode(source)
|
||||
return HttpService:JSONDecode(source)
|
||||
end
|
||||
|
||||
function Http.msgpackEncode(object)
|
||||
return msgpack.encode(object)
|
||||
end
|
||||
|
||||
function Http.msgpackDecode(source)
|
||||
return msgpack.decode(source)
|
||||
end
|
||||
|
||||
return Http
|
||||
|
|
|
|||
2
plugin/msgpack.lua
Normal file
2
plugin/msgpack.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
-- Module alias for msgpack-luau
|
||||
return require(script.Parent.Packages["msgpack-luau"].src.msgpack)
|
||||
|
|
@ -145,7 +145,7 @@ function ApiContext:connect()
|
|||
|
||||
return Http.get(url)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.json)
|
||||
:andThen(Http.Response.msgpack)
|
||||
:andThen(rejectWrongProtocolVersion)
|
||||
:andThen(function(body)
|
||||
assert(validateApiInfo(body))
|
||||
|
|
@ -163,7 +163,7 @@ end
|
|||
function ApiContext:read(ids)
|
||||
local url = ("%s/api/read/%s"):format(self.__baseUrl, table.concat(ids, ","))
|
||||
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.json):andThen(function(body)
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.msgpack):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
|
@ -191,9 +191,9 @@ function ApiContext:write(patch)
|
|||
table.insert(updated, fixedUpdate)
|
||||
end
|
||||
|
||||
-- Only add the 'added' field if the table is non-empty, or else Roblox's
|
||||
-- JSON implementation will turn the table into an array instead of an
|
||||
-- object, causing API validation to fail.
|
||||
-- Only add the 'added' field if the table is non-empty, or else the msgpack
|
||||
-- encode implementation will turn the table into an array instead of a map,
|
||||
-- causing API validation to fail.
|
||||
local added
|
||||
if next(patch.added) ~= nil then
|
||||
added = patch.added
|
||||
|
|
@ -206,13 +206,16 @@ function ApiContext:write(patch)
|
|||
added = added,
|
||||
}
|
||||
|
||||
body = Http.jsonEncode(body)
|
||||
body = Http.msgpackEncode(body)
|
||||
|
||||
return Http.post(url, body):andThen(rejectFailedRequests):andThen(Http.Response.json):andThen(function(responseBody)
|
||||
Log.info("Write response: {:?}", responseBody)
|
||||
return Http.post(url, body)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.msgpack)
|
||||
:andThen(function(responseBody)
|
||||
Log.info("Write response: {:?}", responseBody)
|
||||
|
||||
return responseBody
|
||||
end)
|
||||
return responseBody
|
||||
end)
|
||||
end
|
||||
|
||||
function ApiContext:connectWebSocket(packetHandlers)
|
||||
|
|
@ -234,7 +237,7 @@ function ApiContext:connectWebSocket(packetHandlers)
|
|||
local closed, errored, received
|
||||
|
||||
received = self.__wsClient.MessageReceived:Connect(function(msg)
|
||||
local data = Http.jsonDecode(msg)
|
||||
local data = Http.msgpackDecode(msg)
|
||||
if data.sessionId ~= self.__sessionId then
|
||||
Log.warn("Received message with wrong session ID; ignoring")
|
||||
return
|
||||
|
|
@ -280,7 +283,7 @@ end
|
|||
function ApiContext:open(id)
|
||||
local url = ("%s/api/open/%s"):format(self.__baseUrl, id)
|
||||
|
||||
return Http.post(url, ""):andThen(rejectFailedRequests):andThen(Http.Response.json):andThen(function(body)
|
||||
return Http.post(url, ""):andThen(rejectFailedRequests):andThen(Http.Response.msgpack):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
|
@ -290,39 +293,31 @@ function ApiContext:open(id)
|
|||
end
|
||||
|
||||
function ApiContext:serialize(ids: { string })
|
||||
local url = ("%s/api/serialize"):format(self.__baseUrl)
|
||||
local request_body = Http.jsonEncode({ sessionId = self.__sessionId, ids = ids })
|
||||
local url = ("%s/api/serialize/%s"):format(self.__baseUrl, table.concat(ids, ","))
|
||||
|
||||
return Http.post(url, request_body)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.json)
|
||||
:andThen(function(response_body)
|
||||
if response_body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.msgpack):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
||||
assert(validateApiSerialize(response_body))
|
||||
assert(validateApiSerialize(body))
|
||||
|
||||
return response_body
|
||||
end)
|
||||
return body
|
||||
end)
|
||||
end
|
||||
|
||||
function ApiContext:refPatch(ids: { string })
|
||||
local url = ("%s/api/ref-patch"):format(self.__baseUrl)
|
||||
local request_body = Http.jsonEncode({ sessionId = self.__sessionId, ids = ids })
|
||||
local url = ("%s/api/ref-patch/%s"):format(self.__baseUrl, table.concat(ids, ","))
|
||||
|
||||
return Http.post(url, request_body)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.json)
|
||||
:andThen(function(response_body)
|
||||
if response_body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.msgpack):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
||||
assert(validateApiRefPatch(response_body))
|
||||
assert(validateApiRefPatch(body))
|
||||
|
||||
return response_body
|
||||
end)
|
||||
return body
|
||||
end)
|
||||
end
|
||||
|
||||
return ApiContext
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue