I’ve always avoided this, but I’m wondering if calling RFs on the server can give cleaner code in certain scenarios (which?). Also, what does your rf wrapper look like, do you support (or strictly require?) timeouts like Postie? Do you auto pcall?
Calling RemoteFunctions on the Server Invokes the stated client(s). If you want to send data from a server script to another server script you use Bindable Functions.
There is a good reason why you’ve been avoiding server-client-server communication. Even the Roblox Dev Hub mentions this problem: it’s risky. Client could leave, deliberately not return the signal or simply have poor connection, but all of that could potentially yield the server infinitely. Postie’s intention is good and enables you to add timeouts. Example of use? Take a look at boatbomber’s PlayerPing. He involves Postie and even generates and sends GUID from the server in order to prevent result spoofing. Otherwise, server-client-server communication is again, risky, and most often not needed. One way communication is not only safe, but faster and perhaps performance friendlier. It’s best if server “sends and forgets”, not being concerned about whether client received a signal or not. That’s on client and local scripts. You will also hardly find other “legitimate” reasons and good examples of such communication. Most games don’t even include it, others don’t take appropriate precautions. To conclude, notable examples are definitely rare, because server-client-server signals are often avoided, and most people find an alternative workaround that usually also performs very well if not even better.
Wrapping in pcall() is a good practice, but doesn’t prevent infinite yielding. Use depends on the case.
If you really need to fire remote functions from server, chances are that you are doing some demanding calculations that are actually burden for the server, so think twice and rather find a different route. Perhaps you don’t gain on security but still do on performance. Should you let clients do those calculations?
PS: I don’t have a wrapper, because I never really found server to client remote function practical. If I did need to use server-client-server communication, I’d use Postie.
EDIT (2) @acreol maybe having two way remote events is better.
EDIT (3) Corrected some small spelling errors.
With the proper precautions proposed in the OP, there is really no security risks and w/e performance diff is insignificant. Also @boatbomber’s
GUID is moot because a double RE config must pass a GUID internally to pair the calls (or else Postie couldn’t work like a RF).
There are some cases where Server->Client->Server is superior eg server asking clients to all vote within a 10 second window—imo a neat solution would involve this (if it holds)—and this example is not contrived, see Outlaster. I want to see more places this pattern benefits.
Edit: corrected first link
Edit 2: pinging @Repotted, curious to hear your thoughts on this
@boatbomber used GUID to send a unique code with the signal, and expected the same GUID returned. That prevents client from sending signals again and again customly, because server simply dodges them. It only accepts signal with valid code. As far as usual cases go, GUID doesn’t really help you since clients can hook the remotes and stall sending.
Asking clients to vote? Rather :FireAllClients() and accept their votes via remote events. I don’t see a reason why complicate things. The simplest answer is usually also the correct one.