Documentation

Roblox game servers can't open WebSockets directly. RoSocket opens the WebSocket for you and relays it over plain HTTP: your game sends with a POST and receives by long-polling - the request stays open until something arrives on the socket or the poll times out.

Roblox setup

  1. Enable Game Settings → Security → Allow HTTP Requests.
  2. Create an API token on your dashboard. For published games, store it as an experience secret (e.g. rosocket_token) rather than in source.
  3. Download RoSocket.lua and add it as a ModuleScript named RoSocket in ServerScriptService. It only works from server scripts.
local HttpService = game:GetService("HttpService")
local RoSocket = require(game.ServerScriptService.RoSocket)

RoSocket.configure({
	BaseUrl = "https://rosocket.pyramus.dev",
	Token = HttpService:GetSecret("rosocket_token"), -- or a plain string while testing
})

local socket = RoSocket.connect("wss://echo.websocket.org")

socket:OnOpen(function()
	socket:Send(HttpService:JSONEncode({ hello = "world" }))
end)
socket:OnMessage(function(data, isBinary)
	print("received:", data)
end)
socket:OnClose(function(code, reason)
	print("closed", code, reason)
end)

Module API

MemberDescription
RoSocket.configure(options)BaseUrl, Token (string or Secret), optional PollTimeout (seconds, default 20).
RoSocket.connect(url, protocols?)Opens a socket and returns a Socket. Yields; errors if the server rejects it.
socket.InboundHidden (unparented) BindableEvent fired with ("open"), ("message", data, isBinary), ("error", message), or ("close", code, reason).
socket.OutboundHidden BindableEvent. socket.Outbound:Fire(data, isBinary?) sends a message - hand this to other scripts so they can send without the socket object.
socket:Send(data, isBinary?)Queues a message. Binary messages are base64 strings.
socket:OnOpen / OnMessage / OnError / OnClose(fn)Convenience wrappers around Inbound.Event; return an RBXScriptConnection.
socket:Close()Flushes pending sends and closes the socket.
socket.State"connecting", "open", or "closed".

HTTP API

All endpoints are under /api/v1 and require Authorization: Bearer <token>. Bodies are JSON.

RequestDescription
POST /sockets{ "url": "wss://...", "protocols": [] } → 201 { id, url, state }
GET /socketsLists your open sockets.
POST /sockets/:id/send{ "data": "..." } or { "messages": [{ "data": "...", "binary": false }] }. Messages sent while connecting are buffered.
GET /sockets/:id/poll?ack=N&timeout=SLong-poll (max 25s). Returns { events, state, dropped, closed }. Pass the highest seq you've processed as ack; unacknowledged events are re-sent.
DELETE /sockets/:idCloses the socket.

Event types: open, message (data, binary), error (message), close (code, reason). Each has an increasing seq.

Limits