Implement long-polling message passing

This commit is contained in:
Lucien Greathouse 2018-05-26 00:16:27 -07:00
parent a9d24f1493
commit 92fa52c56f
8 changed files with 93 additions and 39 deletions

View file

@ -22,6 +22,10 @@
"path": "modules/testez/lib",
"target": "ReplicatedStorage.TestEZ"
},
"modules/promise": {
"path": "modules/promise/lib",
"target": "ReplicatedStorage.Rojo.modules.Promise"
},
"tests": {
"path": "tests",
"target": "TestService"

View file

@ -1,5 +1,6 @@
local Promise = require(script.Parent.Parent.modules.Promise)
local Config = require(script.Parent.Config)
local Promise = require(script.Parent.Promise)
local Version = require(script.Parent.Version)
local Http = require(script.Parent.Http)
@ -24,7 +25,8 @@ function ApiContext.new(url, onMessage)
url = url,
onMessage = onMessage,
serverId = nil,
currentTime = 0,
connected = false,
eventCursor = -1,
}
setmetatable(context, ApiContext)
@ -35,9 +37,9 @@ end
function ApiContext:connect()
return Http.get(self.url)
:andThen(function(response)
response = response:json()
local body = response:json()
if response.protocolVersion ~= Config.protocolVersion then
if body.protocolVersion ~= Config.protocolVersion then
local message = (
"Found a Rojo dev server, but it's using a different protocol version, and is incompatible." ..
"\nMake sure you have matching versions of both the Rojo plugin and server!" ..
@ -47,14 +49,43 @@ function ApiContext:connect()
):format(
Version.display(Config.version), Config.protocolVersion,
Config.expectedApiContextVersionString,
response.serverVersion, response.protocolVersion
body.serverVersion, body.protocolVersion
)
return Promise.reject(message)
end
self.serverId = response.serverId
self.currentTime = response.currentTime
self.serverId = body.serverId
self.connected = true
return self:_retrieveMessages()
end)
end
function ApiContext:_retrieveMessages()
if not self.connected then
return Promise.resolve()
end
return Http.get(self.url .. "/subscribe/" .. self.eventCursor)
:andThen(function(response)
local body = response:json()
if body.serverId ~= self.serverId then
return Promise.reject("server changed ID")
end
for _, event in ipairs(body.events) do
self.onMessage(event)
end
self.eventCursor = body.eventCursor
return self:_retrieveMessages()
end, function(err)
self.connected = false
return Promise.reject(err)
end)
end

View file

@ -2,7 +2,8 @@ local HttpService = game:GetService("HttpService")
local HTTP_DEBUG = false
local Promise = require(script.Parent.Promise)
local Promise = require(script.Parent.Parent.modules.Promise)
local HttpError = require(script.Parent.HttpError)
local HttpResponse = require(script.Parent.HttpResponse)

View file

@ -43,12 +43,19 @@ local function main()
local toolbar = plugin:CreateToolbar("Rojo " .. displayedVersion)
local currentSession
toolbar:CreateButton("Connect", "Connect to Rojo Session", "")
.Click:Connect(function()
checkUpgrade()
Session.new()
error("NYI")
if currentSession ~= nil then
warn("Rojo: A session is already running!")
return
end
print("Rojo: Started session.")
currentSession = Session.new()
end)
end

View file

@ -1,7 +1,8 @@
local Promise = require(script.Parent.Parent.modules.Promise)
local Config = require(script.Parent.Config)
local Http = require(script.Parent.Http)
local ApiContext = require(script.Parent.ApiContext)
local Promise = require(script.Parent.Promise)
local REMOTE_URL = ("http://localhost:%d"):format(Config.port)
@ -13,7 +14,9 @@ function Session.new()
setmetatable(self, Session)
local api = ApiContext.new(REMOTE_URL)
local api = ApiContext.new(REMOTE_URL, function(message)
print("Got message:", message)
end)
api:connect()
return self