MirrorNetworking / Telepathy

Simple, message based, MMO Scale TCP networking in C#. And no magic.
MIT License
1.17k stars 136 forks source link

Packets sent from remote connections are unreliable #116

Open PhantomGamers opened 3 years ago

PhantomGamers commented 3 years ago

I thought Telepathy would be ideal for my project as we need to send larger amounts of data during the session.

In the current world I am testing, the host must send the client two larger packets. One 10MB packet and one 35MB packet.

When I test locally, with two instances of the game on the same machine, Telepathy works beautifully for this. However, as soon as someone from outside my network tries to connect the host never receives the packet sent from the client after the client receives the first big packet.

So if I skip the 10MB packet, it will fail to send the packet immediately after.

This packet that fails to send is a struct that contains only a single integer, and it fails 100% of the time.

This is the log from the client's side:

[Info   :NebulaMultiplayerMod] Server connection established
[Debug  :NebulaMultiplayerMod] Packet Sent: HandshakeRequest
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Session.HandshakeRequest to client 0
[Debug  :NebulaMultiplayerMod] Packet Received: HandshakeResponse
[Info   :NebulaMultiplayerMod] Requesting GameHistoryData from the server
[Debug  :NebulaMultiplayerMod] Packet Sent: GameHistoryDataRequest
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.GameHistory.GameHistoryDataRequest to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: ILSRequestgStationPoolSync
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Logistics.ILSRequestgStationPoolSync to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: TrashSystemRequestDataPacket
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Trash.TrashSystemRequestDataPacket to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: PlayerUpdateLocalStarId
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Players.PlayerUpdateLocalStarId to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: ILSArriveStarPlanetRequest
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Logistics.ILSArriveStarPlanetRequest to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: PlayerUpdateLocalStarId
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Players.PlayerUpdateLocalStarId to client 0
[Debug  :NebulaMultiplayerMod] Packet Sent: ILSArriveStarPlanetRequest
[Debug  :NebulaMultiplayerMod] Sending NebulaMessage of type NebulaModel.Packets.Logistics.ILSArriveStarPlanetRequest to client 0
[Info   :NebulaMultiplayerMod] Requesting planet model for 60 Gruis I (ID: 101) from host
[Info   :NebulaMultiplayerMod] Requesting planet model for 60 Gruis II (ID: 102) from host
[Info   :NebulaMultiplayerMod] Requesting planet model for 60 Gruis III (ID: 103) from host
[Info   :NebulaMultiplayerMod] Requesting planet model for 60 Gruis IV (ID: 104) from host
[Info   :NebulaMultiplayerMod] Creating NebulaNetwork.PacketProcessors.Planet.PlanetDataRequest
[Info   :NebulaMultiplayerMod] Requesting DysonSphere for system 60 Gruis (Index: 0)
[Info   :NebulaMultiplayerMod] Creating NebulaNetwork.PacketProcessors.Universe.DysonSphereLoadRequest
[Debug  :NebulaMultiplayerMod] Packet Received: GameHistoryDataResponse
[Info   :NebulaMultiplayerMod] Parsing History data from the server.
[Debug  :NebulaMultiplayerMod] Packet Received: ILSgStationPoolSync
[Debug  :NebulaMultiplayerMod] Packet Received: TrashSystemResponseDataPacket
[Debug  :NebulaMultiplayerMod] Packet Received: ILSArriveStarPlanetResponse
[Debug  :NebulaMultiplayerMod] Packet Received: ILSArriveStarPlanetResponse
[Info   :NebulaMultiplayerMod] Processing NebulaNetwork.PacketProcessors.Planet.PlanetDataResponse
[Info   :NebulaMultiplayerMod] Parsing 81742 bytes of data for planet 60 Gruis I (ID: 101)
[Info   :NebulaMultiplayerMod] Parsing 8718 bytes of data for planet 60 Gruis II (ID: 102)
[Info   :NebulaMultiplayerMod] Parsing 82610 bytes of data for planet 60 Gruis III (ID: 103)
[Info   :NebulaMultiplayerMod] Parsing 81742 bytes of data for planet 60 Gruis IV (ID: 104)
[Info   :NebulaMultiplayerMod] Processing NebulaNetwork.PacketProcessors.Universe.DysonSphereData
[Info   :NebulaMultiplayerMod] Requested factory for planet 60 Gruis III (ID: 103) from host
[Info   :NebulaMultiplayerMod] Creating NebulaNetwork.PacketProcessors.Planet.FactoryLoadRequest

This "FactoryLoadRequest" NetworkMessage is the packet that contains only a single integer, and it fails to arrive on the host, no error is given. The DysonSphereData packet is a NetworkMessage that contains a 10MB byte array in this instance.

This is reproducible 100% of the time.

I've been banging my head against my desk trying to figure out a way to solve this and I just have no idea what is going on. This happens with multiple versions of Telepathy. I've tested the latest version, 1.8, the version that shipped with Mirror 26.2.2, and the 2.0 version from the 2021_worse_in_ccu_tests branch and the behavior is identical for all of them.

EDIT: Also to be super clear since Telepathy can also be used standalone, I am using it within Mirror! So I'm not positive if the issue is with Telepathy itself or perhaps with the TelepathyTransport

PhantomGamers commented 3 years ago

I finally got around to incorporating Telepathy directly in my project, bypassing Mirror, and can confirm that the same behavior exists here so my issue is with Telepathy itself.

The implementation: https://github.com/PhantomGamers/nebula/commit/b32753d11bdb9070450e4cd75b55757085a7f1aa