multitheftauto / mtasa-blue

Multi Theft Auto is a game engine that incorporates an extendable network play element into a proprietary commercial single-player game.
https://multitheftauto.com
GNU General Public License v3.0
1.42k stars 437 forks source link

Streaming over UDP #1622

Open IIYAMA12 opened 4 years ago

IIYAMA12 commented 4 years ago

Is your feature request related to a problem? Please describe. I sometimes want to send messages from client/server as a stream. So sending a message every 1 second to tell the other side that something has updated. This is works fine in most of the cases. But there are also cases that it doesn't matter if the message reached the other side.

For example playing a not high priority audio effect (for specific players), while it is not relevant:

If the TCP protocol is used for streaming, it can sometimes take too long for some players to receive a stream of messages.

Describe the solution you'd like

Describe alternatives you've considered If that is not possible to use UDP for this. Alternatives:

A TCP: Cancelling messages over the same stream if the first messages hasn't been delivered:

Sending a message every 1 second, after 4 seconds none of the messages has been delivered yet. [First message (sending)] [Second message (not sent)] < cancelled [Third message (not sent)] < cancelled [Fourth message (not sent)] < NEW waiting for first message

B An alternative for the function GetLatentEventHandles for non Latent events: https://wiki.multitheftauto.com/wiki/GetLatentEventHandles With this feature cancelling the events is not important, but the status is relevant to prevent killing the network.

C Or having that information per event separated here: https://wiki.multitheftauto.com/wiki/GetNetworkStats messagesInSendBuffer + Event = eventMessagesInSendBuffer

D An event called: onTriggerClientEventDelivered With parameters like for example:

Additional context

Zangomangu commented 4 years ago

I suggest we add a way to send an "unreliable sequenced" RakNet packet from scripting. As the issue explains, there is a use case, where you need to sync something frequently or send an unimportant update. And just like with MTA sync packets, you don't care if the packet is lost because a new one follows right after. You save the overhead of reliable UDP packets, such as ack packets, retransmissions and having to wait for packets to arrive in the right order. And with sequenced packets, only the newest packets are processed and old ones are discarded.

(I don't fully understand IIYAMA12's examples as MTA/Raknet already uses UDP?)

Without having looked deep into it, we could use the existing triggerServer / triggerClient event system, and add two new functions (not sure about naming :-)) triggerServerEventUnreliable triggerClientEventUnreliable That would trigger event handlers on the remote end just like the regular functions, but just sent with different packet reliability.

If we add this feature, would we also allow to set a packet priority? If we did, we should probably limit it to LOW/MEDIUM/HIGH, default to MEDIUM. From RakNet documentation (assuming this still applies to MTA):

IMMEDIATE_PRIORITY, The highest possible priority. These message trigger sends immediately, and are generally not buffered or aggregated into a single datagram. HIGH_PRIORITY, For every 2 IMMEDIATE_PRIORITY messages, 1 HIGH_PRIORITY will be sent. MEDIUM_PRIORITY, For every 2 HIGH_PRIORITY messages, 1 MEDIUM_PRIORITY will be sent. LOW_PRIORITY, For every 2 MEDIUM_PRIORITY messages, 1 LOW_PRIORITY will be sent.