Send the play queue ID to the server
Build / test (push) Successful in 45s
Build / build (push) Successful in 1m12s

The server keeps a play queue per client, identified by the X-Queue-Id
header. The client sends the ID it has for the selected server with every
request and keeps the one in each response, which is new after a reset or a
sync. The IDs are saved per server in the [queues] section of settings.cfg,
so the game goes on with the same queue after a restart.

HttpTransport now passes the response headers on to the client.
This commit is contained in:
Sansan committed 2026-10-07 21:23:37 +02:00
1 parent d21b3e2ce0
commit 4a45e8516d
8 files changed
+212 -16

No files matched your search

+9 -6
View File
@@ -16,8 +16,9 @@ func _init(owner: Node) -> void:
## Requests [param url] and calls [param on_complete] with
## [code](response_code: int, body: PackedByteArray)[/code]. Connection errors and
## timeouts are reported with response code 0. [param headers] are sent as-is; a
## [code](response_code: int, body: PackedByteArray, headers: PackedStringArray)[/code],
## the headers as [code]"Name: value"[/code] lines. Connection errors and timeouts are
## reported with response code 0 and no headers. [param headers] are sent as-is; a
## [param body] is sent as JSON.
func request(
url: String,
@@ -33,12 +34,14 @@ func request(
func(
result: int,
response_code: int,
_headers: PackedStringArray,
response_headers: PackedStringArray,
response_body: PackedByteArray,
) -> void:
http_request.queue_free()
on_complete.call(response_code if result == HTTPRequest.RESULT_SUCCESS else 0,
response_body)
if result != HTTPRequest.RESULT_SUCCESS:
on_complete.call(0, response_body, PackedStringArray())
return
on_complete.call(response_code, response_body, response_headers)
)
var all_headers: PackedStringArray = headers.duplicate()
if method == HTTPClient.METHOD_PUT || !body.is_empty():
@@ -47,4 +50,4 @@ func request(
if error != OK:
http_request.queue_free()
push_error("Could not send request to %s (error %d)" % [url, error])
on_complete.call(0, PackedByteArray())
on_complete.call(0, PackedByteArray(), PackedStringArray())
+36 -2
View File
@@ -6,6 +6,11 @@ extends Node
## goes through [member transport]; tests replace it with a fake to answer requests
## without a running server.
##
## The server keeps a play queue for each client, identified by the [code]X-Queue-Id[/code]
## header. The client sends the ID it has for the server with every request and keeps the
## one in each response, which is new when the server started a new queue (after a reset
## or a sync). The IDs are kept in [code]Settings.queue_ids[/code], which saves them.
##
## Requests need a token, which the client gets with [code]Settings.api_password[/code]
## the first time it is needed and then reuses. When the server answers 401 (the token
## expired, or the server restarted), it gets a new token and sends the request once
@@ -21,6 +26,8 @@ extends Node
const API_PATH: String = "/api/v1"
## Sent when asking for a token, so the server can tell its clients apart.
const CLIENT_TYPE: String = "godot"
## Header with the ID of the client's play queue, in requests and responses.
const QUEUE_HEADER: String = "X-Queue-Id"
## Sends the actual HTTP requests. Swap it out in tests.
var transport: HttpTransport
@@ -301,6 +308,25 @@ func clear_token() -> void:
_token_server = ""
# Queue IDs
## The ID of the play queue on the selected server, or "" before the server has sent one.
func queue_id() -> String:
return Settings.queue_ids.get(Settings.default_path, "")
# Keeps the queue ID in [param headers] from [param server] when it is new
func _remember_queue_id(server: String, headers: PackedStringArray) -> void:
var prefix: String = QUEUE_HEADER.to_lower() + ":"
for header: String in headers:
if !header.to_lower().begins_with(prefix):
continue
var id: String = header.substr(prefix.length()).strip_edges()
if !id.is_empty() && Settings.queue_ids.get(server, "") != id:
Settings.set_queue_id(server, id)
return
# Generic requests
## Requests [param path] and calls [param on_done] with the parsed JSON.
@@ -415,11 +441,19 @@ func _send_once(
func _send(
path: String, method: int, token: String, on_complete: Callable, body: String = "",
) -> void:
var server: String = Settings.default_path
var headers: PackedStringArray = []
if !token.is_empty():
headers.append("Authorization: Bearer " + token)
transport.request(Settings.default_path + API_PATH + path, method, on_complete, headers,
body)
var queue: String = Settings.queue_ids.get(server, "")
if !queue.is_empty():
headers.append("%s: %s" % [QUEUE_HEADER, queue])
transport.request(server + API_PATH + path, method,
func(response_code: int, response_body: PackedByteArray,
response_headers: PackedStringArray) -> void:
_remember_queue_id(server, response_headers)
on_complete.call(response_code, response_body)
, headers, body)
func _handle_response(