Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REVISION] Asynchronous Reciever on Server #32

Closed
john-bv opened this issue Mar 12, 2022 · 0 comments · Fixed by #35
Closed

[REVISION] Asynchronous Reciever on Server #32

john-bv opened this issue Mar 12, 2022 · 0 comments · Fixed by #35
Assignees
Labels
Complete The code review for this issue has been completed; and is now being finalized.

Comments

@john-bv
Copy link
Member

john-bv commented Mar 12, 2022

Currently, the api for starting a RakNet Server is not very dynamic in that it only supports a one way solution making it hard to throw your own solution on top of the current one.

The issue lies within creating a RakNet Server and starting one up, currently you need to invoke the start function which will spawn all threads and start waiting for clients, (as expected). However, the issue lies in the fact as the end user, you have no access to the connection itself or the listener, this revision aims to change that. Consider the current implementation:

let server = RakNetServer::new(String::from("0.0.0.0:19132"));
let channel = netrex_events::Channel::<RakEvent, RakResult>::new();
let mut listener = |event, _| {
    match event {
        RakEvent::ConnectionCreated(address) => {
            println!("[RakNet] [{}] Client connected", address);
        }
    };
    None
};
channel.receive(&mut listener);

let v = start(server, channel).await;
v.0.await;

The revision for the code above would allow the end user to optionally process either each packet from each connection or each raw packet using asynchronous methods.

For example, the new way to handle connections with this revision may look something like:

async fn spawn_server() {
    let server = Server::new("0.0.0.0:19132");

    // If this is used, the server will spawn a thread to manage the connections.
    // When the thread is spawned, the handle to it is returned.
    let handling_thread = server.listen();

    loop {
        // Waits for a packet. Resolved when a packet from a connection is recieved.
        // For raw packets, use `server.recv()`
        let pk_processor = server.process().await?;
        let connection = pk_processor.connection.as_ref().lock();

        // do your handling here.
        // keep in mind that connection is a mutable reference.
        
        // For example, we can hijack the servers packet processing.
        pk_processor.prevent_default();

        // The server is waiting on a packet to be set within the packet processor.
        // Using this method will resolve that future.
        pk_processor.reply_with(DisconnectPacket::new().into());

        // Alternatively, to use default behavior you can use:
        pk_processor.proceed();
    }
}

This change is necessary because of how restrictive the current implementation is. This revision would allow you to have better control of the raknet server as well as it's processing of packets, which currently is done through the disaster of events, which should only be used for server plugins.

@john-bv john-bv self-assigned this Mar 12, 2022
@john-bv john-bv closed this as completed Oct 31, 2022
@john-bv john-bv added the Complete The code review for this issue has been completed; and is now being finalized. label Jun 17, 2023
@john-bv john-bv linked a pull request Aug 21, 2023 that will close this issue
@NetrexMC NetrexMC locked and limited conversation to collaborators Sep 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Complete The code review for this issue has been completed; and is now being finalized.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant