Listener → Server Push

Server Push

Push events are reliable server-to-client messages sent by app:Push() over a RemoteEvent — every event is guaranteed to arrive exactly once.

How push events arrive

On the server you call app:Push(player, event, data). On the client you subscribe with listener:On(event, fn). Listener routes the incoming RemoteEvent payload to the matching handler automatically — no extra setup needed.

-- SERVER (Script)
local app = RoExpress.GetApp()

app:Get("round/start", function(req, res)
    -- push to everyone when a round begins
    app:PushAll("round.start", { duration = 120 })
    res:Send({ ok = true })
end)

-- CLIENT (LocalScript)
local listener = RoExpress("Listener")

listener:On("round.start", function(data)
    HUD:ShowTimer(data.duration)
end)

Reliability guarantee

Push uses Roblox's RemoteEvent. This means every event fired at a specific player is guaranteed to arrive — Roblox's network layer will retransmit until acknowledged. Push is the right channel when missing an event would break game logic (round start/end, inventory updates, match results).

PropertyValue
TransportRemoteEvent (reliable)
DeliveryGuaranteed — every event arrives
OrderOrdered per-player
Server APIapp:Push(player, event, data) · app:PushAll(event, data) · app:PushTo(players, event, data)

Event naming convention

Event names are plain strings — any string the server and client agree on. A common convention is noun.verb or domain.action to avoid collisions between systems:

-- recommended naming patterns
"round.start"       -- round started
"round.end"         -- round ended with results
"player.data"       -- initial player data push on join
"inventory.update"  -- coins or items changed
"match.result"      -- win/loss outcome

Round lifecycle example

local listener = RoExpress("Listener")

listener:On("round.start", function(data)
    print("Round starting — duration:", data.duration)
    HUD:StartTimer(data.duration)
    HUD:ShowMessage("Round started!")
end)

listener:On("round.end", function(data)
    print("Round over — winner:", data.winner)
    HUD:StopTimer()
    HUD:ShowWinner(data.winner)
end)
Same handler, both channels. listener:On("round.start", fn) receives events from both app:Push() (reliable) and broadcast:Emit() (unreliable). For round lifecycle events you almost always want Push. See Broadcast for the unreliable counterpart.

See also

← Listener  ·  Subscribe | On, Once, Off reference  ·  Broadcast | unreliable channel comparison  ·  App Push | server-side push API