Can I combine RemoteEvent and RemoteFunction listeners?


#1

I currently have two scripts, one to handle RemoteEvents and the other to handle RemoteFunctions. I know I can have all the RemoteEvents handled in one script because the connect functions would create new threads and hence allow the other event connections to work. However, since the RemoteFunctions are handled by creating a function, I’m not very sure whether they would yield the main thread and thus prevent the rest of the connections from working. I’m really not sure if I’m even saying things correctly.

--RemoteEventsScript.

game.ReplicatedStorage.RE1.OnServerEvent:Connect(function()
    --Stuff.
end)



--RemoteFunctionsScript.

game.ReplicatedStorage.RF1.OnServerInvoke = function()
    --Stuff.
end

With that said, in the first place, can I even have multiple RemoteFunction listeners in the script on its own?

If they do yield the main thread then actually could I do:

game.ReplicatedStorage.RF1.OnServerInvoke = spawn(function()
    --Stuff.
end)

I’m probably making a lot of huge mistakes…


#2

So, it would seem your understanding of RemoteFunctions is incorrect. Let’s fix that!

When you assign a callback function to a RemoteFunction, the contents of that function have no impact on your current thread. It is just an assignment afterall.

remoteFunction.OnServerInvoke = function ()
    -- Stuff.
end)

otherRemoteFunction.OnServerInvoke = function ()
    -- Stuff.
end)

In this example, both RemoteFunctions will have callback listeners assigned one after another. The thread does not yield during each assignment.


When a RemoteFunction is invoked, each invocation has its own thread. These threads can yield without affecting your main script or interacting with eachother.
remoteFunction.OnServerInvoke = function ()
    wait(2)
end

while true do
    wait(1)
    print("Foo")
end

In this example, “Foo” will continue to be printed every second, even when the RemoteFunction is invoked.


RemoteFunctions, much like RemoteEvents, run in their own threads when invoked, the major difference coming from that calling the Invoke methods will yield the calling thread until the callback function has returned.
remoteFunction.OnServerInvoke = function ()
    wait(2)
    return "Bar"
end

This function will yield for 2 seconds before returning “Bar”.

local result = remoteFunction:InvokeServer()
print(result)

The call to InvokeServer will yield for 2 seconds, and then return “Bar”. The script will then print out “Bar” to the output.


Putting this all together, you can mix RemoteFunction callbacks and RemoteEvent listeners in the same script as you choose. You don't need to use Spawn, or handle any of the threads yourself.

#3

Sorry I really don’t understand what callback means even after reading some articles.


#4

To explain it simply, let’s use some examples.

Client Script:

local result = remoteFunction:InvokeServer()
print(result)

Server Script:

remoteFunction.OnServerInvoke = function()
return true
end

Client Script calls Server Script.
Client Script: :wave: @Server Script, I need some info from you. What’s your return value?
Client Script is waiting for a response, so it doesn’t go ahead with the print statement.
Server Script calls back.
Server Script: :slight_smile: @Client Script, I gotcha - it’s the boolean true!
Client Script: :smile: Thanks!
Client Script receives the boolean true that was returned from the invocation (the “conversation”) of the remote function. Client Script can now print the result, which will be…
true!

Essentially, the callback function is the function that returns a value to the calling script.
I hope this clears it up for you.


#5

A callback function is just a function which you register to be ‘called-back’ in the future, not unlike somebody calling you back on your phone. Stack overflow has a nice explanation of this. https://stackoverflow.com/questions/824234/what-is-a-callback-function

In my example, the callback function is the function you’re assigning to OnInvoke. It’ll be ‘called-back’ in the future, when somebody invokes the remote.


#6

Oh no, now I’ve got even more questions and I’m not sure if I should continue in this topic…


#7

Uh oh!
If something’s still confusing you, I’m sure there are many of us that can answer your questions (or alternatively, if you prefer to PM someone, you can do that too)!


#8

So like Roblox made it so that OnServerInvoke is a callback function and maybe it’s possible that Roblox could make it an event? I’m not sure but that’s just a random thought that’s bugging me a lot now.

And also, how does the InvokeServer() result get stored?

I have a sprint script that is a LocalScript that has to check if the player’s LegBroken.Value is true. And if at any point while the player is still running and LegBroken.Value becomes true, the sprinting would stop. I know mouse.KeyDown is deprecated and I’ll change this sometime soon.

--Local script.

local running = false

mouse.KeyDown:Connect(function(key)
    local CheckLegBroken = game.ReplicatedStorage.RF1:InvokeServer()
    
    if string.byte(string.lower(key)) == 48 and CheckLegBroken == false then
        running = true
        
        local KeyConnection = mouse.KeyUp:Connect(function(key)
            if string.byte(key) == 48 then running = false end
        end)
        
        --Increase speed.
        
        repeat wait() until running == false or CheckLegBroken == true
        KeyConnection:Disconnect()
        
        --Decrease speed.
    end
    
end)



--Script.

game.ReplicatedStorage.RF1.OnServerInvoke = function(player)
    return player.Data.LegBroken.Value
end

The thing is that the repeat wait() until running == false or CheckLegBroken == true seems like it does not get an updated value from CheckLegBroken and I have to actually do this:

repeat
    wait()
    local CheckLegBroken2 = game.ReplicatedStorage.RF1:InvokeServer()
until running == false or CheckLegBroken2 == true

I’m really not sure how it works but now I would be invoking the function a lot of times and there might be lag? I’m really not sure what’s going on anymore or what to do…


#9

I think that your solution with a repeat loop should work properly - perhaps what you can do is have the wait period be longer in order to reduce the number of times you’re calling the RemoteFunction.


#10

Ok I think I understand callback functions a bit better now. Can I say this: A function is something that just does things, but a callback function would have to return something to whatever called it.

--Function.

function Hello()
    print("Hello.")
end

Hello()



--Callback function.

function Hello()
    return "Hello"
end

local h = Hello()

I hope that’s correct.