Search Unity

Resolved Can I use MultiNetworkDriver for both IPv4 and IPv6?

Discussion in 'Unity Transport' started by Kichang-Kim, Mar 17, 2023.

  1. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    Hi. I managed multiple NetworkDriver for handling both IPv4 and IPv6 connection. I created abstraction connection struct which has internal driver index for its source.

    Then I found that Unity Transport 2.0.0-pre.7 introduces "MultiNetworkDriver" that seems to be best fit for above case.

    So can MultiNetworkDriver handles multiple UDP network driver which has only different binding address?

    THanks.

    Related post:
    https://forum.unity.com/threads/cas...accept-connection-from-ipv4-endpoint.1215861/
     
    Last edited: Mar 17, 2023
  2. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Yes! That's exactly one of the use cases we had in mind when we designed this feature. It's even one of the examples in our documentation. I'm happy to read that this will be immediately useful to you. Please don't hesitate if you have any questions.
     
    Kichang-Kim likes this.
  3. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    The link to the example (the one you posted now) is not available anywhere in the manual (at lest not in the index on the right side) as far as I see. I mention this in case you forget to add it. I have seen the example mentioned in the changelog, but I was not able to find it.

    Also your update is just in time for me too as I today started implementing the migration of my custom networking layer from UNET to Transport.
     
  4. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    The sidebar does have a "cross-play" section that links to the page I link to. I'm guessing it might not appear for you because the browser is using a cached version of the sidebar. I know I had to force a cache update to get it to appear (Shift+F5 or Ctrl+F5 depending on your browser).
     
  5. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    Yes that was the case, it is working now, thank you.
     
  6. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    Looks like it is not only the left menu, but the individual reference pages also need a hard refresh to show the newest version. Which makes the whole documentation more difficult to use. I only find that I need to do the cache refresh because I have seen that there is a <summary> section in the Transport source code, but it is not visible on the reference page. So I guessed that I have to refresh.

    Even though I know it is not related directly to Transport, I think this should be somehow fixed by Unity as it seems like a big problem.
     
  7. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    @simon-lemay-unity Hi. My project has P2P feature, so client and server share the most of code. The problem is that MultiNetworkDriver and NetworkDriver does not implement any shared interface so all of my code should have annoying conditional statement like this:
    Code (CSharp):
    1. if(useMultiNetworkDriver)
    2. {
    3.     var multiNetworkDriver = ...
    4.     multiNetworkDrvier.Send(...)
    5. }
    6. else
    7. {
    8.     var newtorkDriver = ...
    9.     newtorkDriver.Send(...)
    10. }
    Main problem is that MultiNetworkDriver does not have Connect() method so I can't use it for client side.

    Is there any other method for handling both MultiNetworkDriver and NetworkDriver transparently?
     
  8. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    I would like to see this feature too (even though I will not use P2P) as it would simplify the code. Both the client and the server have to do similar things like sending and receiving data not being able to use MultiNetworkDriver for both sides is a complication that could be avoided.
     
    Last edited: Mar 20, 2023
  9. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Currently there is not. We thought about adding an interface for common driver operations, but ultimately opted not to include one at this point because such a solution wouldn't work within Burst-compiled code. We're very much open to revisiting this decision however if there is a need for it.

    We also thought about supporting client drivers in
    MultiNetworkDriver
    , but again opted not to at this point because the semantics for clients are less clear. For example, let's say we were to add a
    Connect
    method, which driver should it connect?

    Between the two, is there one approach that would better fit your use case? If we add an interface for common driver operations, what would you expect this interface to cover? Sending data and popping events? Scheduling updates (which would preclude the interface from covering the concurrent versions of the
    NetworkDriver
    and
    MultiNetworkDriver
    )? I'm curious to read about what an ideal solution would look like from a user's point of view.
     
  10. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    Wouldn't the client MultiNetworkDriver only need one NetworkDriver? Connect() could probably safely use the first driver from the list.
     
  11. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    That's certainly one option, but I'm not keen on creating an implicit "role" for
    MultiNetworkDriver
    (e.g. that it could be either a server or a client without it being made very clear in the API). Plus, this will break down if we ever want to support mixed servers and clients in the same
    MultiNetworkDriver
    . I could see this being useful for mesh networking scenarios, for example. If we're going to support client drivers in
    MultiNetworkDriver
    , personally I'd rather we provide a more complete support for it.
     
  12. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    In my case, I created my own wrapper for this case:
    Code (CSharp):
    1. struct DriverWrapper : IDisposable
    2. {
    3.     public bool UseMultiNetworkDriver;
    4.     public MultiNetworkDriver MultiNetworkDriver;
    5.     public NetworkDriver NetworkDriver;
    6.     public bool IsCreated => this.UseMultiNetworkDriver ? this.MultiNetworkDriver.IsCreated : this.NetworkDriver.IsCreated;
    7.  
    8.     public NetworkConnect Connect(...)
    9.     {
    10.         if(this.UseMultiNetworkDriver)
    11.         {
    12.             throw new NotSupoortedException();
    13.         }
    14.         else
    15.         {
    16.             return this.NetworkDriver.Connect(...);
    17.         }
    18.     }
    19.  
    20.     public int Send(...)
    21.     {
    22.         if(this.UseMultiNetworkDriver)
    23.         {
    24.             return this.MultiNetworkDriver.Send(...);
    25.         }
    26.         else
    27.         {
    28.             return this.NetworkDriver.Send(...);
    29.         }
    30.     }
    31.  
    32.     // And other public methods ...
    33. }
    34.  
    35.  
    36. struct MySendJob : IJob
    37. {
    38.     [NativeDisableContainerSafetyRestriction] // <= This attribute need for Unity safety check!
    39.     public DriverWrapper Driver;
    40.  
    41.     // My shared application code for common operation ...
    42. }
    It may be inefficient, but works :)
     
  13. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    Or it may be useful if I can convert NetworkConnection of single NetworkDriver to MultiNetworkDriver's like this:
    Code (CSharp):
    1. NetworkDriver driver = ...;
    2.  
    3. var connection = driver.Connect(...);
    4.  
    5. MultiNetworkDriver multiDriver = ...;
    6.  
    7. multiDriver.AddDriver(driver);
    8.  
    9. var connectionForMultiDriver = multiDriver.ConvertConnection(driver, connection);
    10.  
     
    Last edited: Mar 22, 2023
  14. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    If you were able to add non-server drivers to a MultiNetworkDriver and connect them by ID, would this solve your problem? For example:
    Code (CSharp):
    1. var driver = NetworkDriver.Create();
    2. var multiDriver = MultiNetworkDriver.Create();
    3.  
    4. var driverId = multiDriver.AddDriver(driver);
    5. var connection = multiDriver.Connect(driverId, endpoint);
    (To clarify, the above code does not work in 2.0.0-pre.7. It's just an example of what the API could look like.)
     
    Kichang-Kim likes this.
  15. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Also, thank you for posting your solution with the driver wrapper! This helps us define what is the best way to address your problem. I now see that an interface might not be ideal, since it would not include operations like
    Connect
    . Also, using an interface would require you to use generic jobs, which can be annoying to work with.
     
  16. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    DriverId seems to be simple and easy to use. It can solve my case.
     
    simon-lemay-unity likes this.
  17. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    Can I use the same port for UDPNetworkInterface and WebSocketNetworkInterface? In the documentation example you use different ports, but I used the same and I got no errors.
     
  18. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Great! Thanks for the feedback! We'll try to get this done ASAP.

    Yes, you can use the same port. The UDP interface uses a UDP port, and the WebSocket interface uses a TCP port. Of course, if you were (for whatever reason) to add two WebSocket drivers, they wouldn't be able to use the same port (unless bound to distinct non-wildcard local IP addresses).
     
    MariuszKowalczyk likes this.
  19. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Small update on this: version 2.0.0-pre.8 has been released and contains the change to allow client drivers in
    MultiNetworkDriver
    . The documentation has been updated with an example, but it's basically the same usage as the sample code I posted above.
     
    Kichang-Kim likes this.
  20. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    New MultiNetworkDriver makes my code be simple and clear. I can't find any issue at this time. Thanks.
     
    JohannRw and simon-lemay-unity like this.