Skip to main content

Remote Functions

RemoteFunctions are for two way communicates between the server and client. This means the sender is able to receive a response from the receiver. Flamework's RemoteFunctions implementation use promises which allow you to avoid any dangerous yields, errors, etc. All requests have a timeout of 10 seconds.

Whilst it is not recommended, Flamework does support ServerToClient remote functions. Flamework avoids common pitfalls by implementing timeouts and cancellation (such as a player leaving) using promises.

Creation

You can use the Networking.createFunction macro to create your network handler. This will contain all your events for both server and client and you can also configure your middleware.

import { Networking } from "@flamework/networking";

interface ClientToServerFunctions {
function(param1: string): number;
}

interface ServerToClientFunctions {
function(param1: string): number;
}

// Returns an object containing a `server` and `client` field.
export const GlobalFunctions = Networking.createFunction<ClientToServerFunctions, ServerToClientFunctions>();

// It is recommended that you create these in separate server/client files,
// which will avoid exposing server configuration (including type guards) to the client.
export const ServerFunctions = GlobalFunctions.createServer({ /* server config */ });
export const ClientFunctions = GlobalFunctions.createClient({ /* client config */ });

Using Functions

Once you've declared all your functions, it's time to use them. You can access your functions simply by indexing the Functions object.

A player? parameter in the following examples means that the parameter only exists on the server, and is absent on the client.

Invoking Functions

Invoke a request and wait for a response.

// Invoke a function
Functions.function.invoke(player?, "my parameter!").then((value) => ...);

// Shorthand syntax, equivalent to Functions.
Functions.function(player?, "my parameter!").then((value) => ...);

// Predict, simulates a request being sent
Functions.function.predict(player?, "my parameter!").then((value) => ...);

Handling Functions

You can only connect one handler to each function. Calling setCallback more than once will override the existing handler but will result in a warning being outputted.

// With a normal function
Functions.function.setCallback((player?, param1) => {
print("This is", param1);
return math.random(1, 100);
})

// With an async function
Functions.function.setCallback(async (player?, param1) => {
print("This is", param1);
return await myAsyncNumberGenerator(1, 100);
})

Errors

Flamework's networking exposes a NetworkingFunctionError enum which is used whenever a RemoteFunction request is rejected.

NameDescription
TimeoutThe request surpassed the timeout length.
CancelledThe request was cancelled by the receiver.
BadRequestThe request was rejected by the receiver due to invalid arguments.
InvalidResultThe request was processed by the receiver, but an invalid result was returned.
UnprocessedThe request was not processed by the receiver.

Handling errors

Flamework's RemoteFunctions return promises which allows you to handle them the same as any other promise. Flamework always passes a NetworkingFunctionError as the rejection value, which tells you the reason the request failed.

Events.function.invoke()
.then((value) => print("I successfully got", value))
.catch((reason) => {
if (reason === NetworkingFunctionError.Timeout) {
warn("My request timed out!");
} else {
warn("A different error occurred:", reason);
}
})