Sign in to follow this  
micaww

rage-rpc: Universal, asynchronous Remote Procedure Call implementation for RAGE

Recommended Posts

For those who use React for their front-end, here are a couple super basic React Hooks that I use to help accept events in components. Enjoy!

import rpc from 'rage-rpc';

/**
 * Register an RPC handler for the lifetime of the component.
 * @param procedure - The name of the procedure
 * @param callback - The callback to handle the procedure
 * @param deps - Hook dependencies. When changed, the hook will be reregistered
 */
export function useRPCHandler(procedure: string, callback: rpc.ProcedureListener, deps: any[]){
    useEffect(() => {
        rpc.register(procedure, callback);

        return () => {
            rpc.unregister(procedure);
        };
    }, deps);
}

/**
 * Register an event handler for the lifetime of the component.
 * @param event - The name of the event
 * @param callback - The callback to handle the event
 */
export function useEventHandler(event: string, callback: rpc.ProcedureListener){
    useEffect(() => {
        rpc.on(event, callback);

        return () => {
            rpc.off(event, callback);
        };
    });
}

This is ready for TypeScript, but you can easily use it in a JavaScript environment by simply removing the types in the arguments.

Here is an example component using both hooks:

import React from 'react';
import ReactDOM from 'react-dom';
import { useRPCHandler, useEventHandler } from './hooks'; // wherever you just put those two hook functions

// This is a basic HUD component that shows a money value

function HUD(){
    const [money, setMoney] = useState(0);
    const [visible, setVisible] = useState(false);
  
    useRPCHandler('isMoneyVisible', () => visible, [visible]);
    useEventHandler('setMoney', amount => setMoney(amount));
  
    if(!visible) return null;
    return (
        <h1>${money.toLocaleString()}</h1>
    );
}

ReactDOM.render(
    <HUD/>,
    document.getElementById('root')
);

 

With this being rendered in any CEF browser, you can now use those 2 hooks from anywhere on RAGE:

import rpc from 'rage-rpc';

// SERVER-SIDE
const player = mp.players.at(0);
rpc.callBrowsers(player, 'isMoneyVisible').then(visible => {
    if(visible){
        console.log(`${player.name}'s money is visible!`);
    }else{
        console.log(`${player.name}'s money isn't visible!`);
    }
});
rpc.callBrowsers(player, 'setMoney', 999999);

// CLIENT-SIDE OR IN ANY BROWSER
rpc.callBrowsers('setMoney', 5000);

 

Note: Notice that useRPCHandler requires a dependency array and useEventHandler does not. This is because registering RPC handlers in the browser requires an event to be sent to the client to tell the client that this browser instance can accept RPC calls. It's best to provide as many dependencies as your handler uses so that it will be unhooked and rehooked the minimum amount of times. This also prevents your callback from capturing stale values.

useEventHandler can re-register itself as many times without any performance drawback, as the client doesn't care if it has a handler or not, so it doesn't notify the client that it has a handler for events.

  • Like 2

Share this post


Link to post
Share on other sites

I wondered if there would be situation, in which we made a serverside call to client, and returns a Promise, which resolves after some time. In the meanwhile client has crashed or left, and I made await on this Promise in a command at serverside. I guess not resolved promises are nothing wrong itself, but to make my sleep calm I have to ask it, if in your opinion would be there some consequences or better to avoid this situation? Obviously code after await won't be reached I guess.

async function someCommandCall () {
  await rpc.callClient(player, 'waitForKeyInput') // resolves after time and client has crashed
  console.log('resolved')
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.