Deprecation in this case (and in general) does not change behavior – connect/Connect behave the same.
I can confirm the broken behavior.
--client fires ReplicatedStorage.RemoteEvent during this time
wait(10)
local conn
conn = game.ReplicatedStorage.RemoteEvent.OnServerEvent:connect(function()
conn:disconnect()
end)
The expected behavior is that the connection will disconnect after OnServerEvent invokes the passed function, but conn:disconnect() actually errors with attempt to index conn a nil value because the passed function is being invoked before the connection has finished being set up and sets the conn variable. Removing the wait resolves the issue.
You’re touching on a larger issue. RemoteEvents are flawed in the following way: interacting with the RemoteEvent’s signal (i.e. via Connect or Wait) can cause the signal the fire. This has several implications:
Only the first connected listener will receive any queued events.
Multiple threads cannot use Wait without missing queued events.
Wait and Connect cannot be mixed: Wait receives queued events one at a time, but a single Connect will drain the entire queue, leading to Wait missing queued events.
More generally, in any case where a signal is fired via its own Connect or Wait method, one cannot reliably use multiple Connects and Wait at the same time. Other than RemoteEvents, no other signal has this behavior. Also consider that there are no APIs that allow Connect or Wait to be “listened in” on. Based on all this, one could conclude that being unable to listen in on signals like this is a necessary feature in how signals are designed, one which RemoteEvents have violated.
I think the best solution is to remove the automatic dequeuing behavior, and instead add a method to RemoteEvent that dequeues and returns a list of any queued events. This will require developers to handle queued events explicitly, but it will give them time to setup listeners. More importantly, RemoteEvents will no longer violate signal design.
For now, in order to use a RemoteEvent safely, it should have at most one listener, or one thread handling Wait.
This behavior is only really encountered when doing weird things. If the remote is created and listened to server side then it should be created way before any client is even ready to fire it.
In any case, the client should send a signal to the server saying “I’m ready” once it loads through one of your remotes so you know it can fire and receive now. This solves the issue on both ends and is ideally how one should go about this async stuff.
I’m aware of ways to solve this – most of my Remotes have a single connection. Here, I was being lazy and discovered buggy behavior. Regardless of the best practices, an event should not fire before :connect returns.
As to why I was doing this, I was being a bit lazy: this event should only accept being fired once, and I don’t want to have to keep track of players in a table and add/remove them when they join/leave. Instead, I connected to the event when the player is allowed to fire it and removed the connection when they’ve fired it.
Bumping this 4 years old issue, because I confirm that it is still happening. It is in fact very annoying, as you have to yield before being able to disconnect.
Hello! Thank you for the report. The original script provided as a repro doesn’t exist any longer (understandably) though I have tried to do so on my end based on the snipped provided here but was unable to repro it either.
Does the issue still exist or has it been resolved?