Search Unity

[LLAPI] [SOLVED] How to use second level of UNet API to handle messages?

Discussion in 'UNet' started by Inaetaru, Jun 21, 2017.

  1. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    After a lots of struggle with HLAPI I decided to use LLAPI. I studied items from following chart and I decided that second level (Messaging & Serialization) is the best for me.



    I use Transport to create server and clients and to connect them. Then I want to use Connection (+ Reader and Writer) to handle connections and messages. However every time I call RegisterHandler on Connection instance, it causes null reference exception.

    From UNet source code, I found out that the null object is (probably) m_MessageHandlers in Connection class. However, I wasn't able to find any way how to set a value to it. All I was able to find are calls using NetworkClient and NetworkServer - but I don't want to use this, third, level.

    So, the question is: can I use Connection's handling messages without NetworkClient and NetworkServer? [edit: and if yes, how?]

    EDIT - SOLUTION
    :

    No, we can't. See post bellow.

    Continuation of original post:

    Now, what follows is usual list of details about my project;

    How I create server
    • Create a host using NetworkTransport.AddHost
    • Receive events using NetworkTransport.ReceiveFromHost
    • When I receive a ConnectEvent, I create new Connection instance
    • Call Connection.Initialize using data from NetworkTransport.GetConnectionInfo
    • Call Connection.RegisterHandler - null reference exception
    How I create client
    • Create host using NetworkTransport.AddHost
    • Connect to server with NetworkTransport.Connect
    • Receive events using NetworkTransport.ReceiveFromHost
    • When I receive a ConnectEvent, I create new Connection instance (if the connection id is same as returned from NetworkTransport.Connect - otherwise, disconnect)
    • Call Connection.Initialize using data from NetworkTransport.GetConnectionInfo
    • Call Connection.RegisterHandler - null reference exception
    Why I don't want to use HLAPI
    Lots of reasons. For example:
    • No way how to easily implement offline support. (Solution "just start server locally and don't accept clients" doesn't work well in certain environments, like disconnected PC.)
    • When user disconnects, there is no nice way how to fluently transition networked object they owns. Instead, these objects are destroyed immediately, abruptly. (There is solution, yes, but it's a hack.)
    • The most high level classes are actually unusable in real game (NetworkLobbyManager, NetworkTransform). For example the lobby manager doesn't allow fluent transition between scenes. No fade-in, fade-out. Only with hacks.
    • Many more
    Why I don't want to use third level - NetworkClient and NetworkServer
    • I don't want to freeze my network system to star. I'm working on state-tracking system (imagine a matrix - cells contain states, rows represents objects, cols represents time points) which would create layer between the game and networking. This system can easily share state updates (from local-owned objects, like input) with all other clients directly instead of passing through server while server still can validate them later. Direct connection would result in less lag. Why do I want to decrease lag so badly? The game I'm working on is action genre, however it's not standard shooter (with infinite-speed projectiles so server can easily calculate the hit) but projectiles are also simulated (by design). In this case, even relatively small lag causes ugly projectile spawning (jumps). Using the technique which displays delayed state doesn't work either - again, because of these projectiles. (Note: I already implemented most of the logic in HLAPI without state-tracking system, then I found out this problem, then I designed the state-tracking system and then I realized that HLAPI is not good idea for that.)
     
    Last edited: Jun 29, 2017
    TwoTen likes this.
  2. Deleted User

    Deleted User

    Guest

    Nowadays overriding means hack ?

    Code (CSharp):
    1.     public override void OnServerDisconnect(NetworkConnection conn)
    2.     {
    3.         //NetworkServer.DestroyPlayersForConnection(conn);
    4.         //Do not destroy player object after client has been disconnected.
    5.     }
     
  3. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    If overriding OnServerDisconnect and postpoing DestroyPlayersForConnection is going to solve the problem completely, then I apologize for proving wrong information.

    It has been some time since I was trying solve this problem (my current HLAPI solution is just relay for messages between network and actual instances not depending on network due to offline-mode constraint), so I apologize for all mis-information. What I remember, this solution was working only for player objects - not for client-owned, non-player ones.

    Btw. what I call "hack" is to take original message handler, provide my own, react when receive the message (for example play animation), copy message content and call original handler with copied message later. That was the only solution I was able to find to fully control transitions.
     
    Deleted User likes this.
  4. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    261
    Based on my limited understanding, the simple answer is yes. NetworkClient and NetworkServer are written using the messaging stuff. However, what I would suggest instead of rewriting them is getting the source from https://bitbucket.org/Unity-Technologies/networking and modifying to suit your needs, or adding your own new connection management classes using the HLAPI classes as a guide. Master Server Framework (see my sig) might also give you a useful starting point.
     
  5. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    Hm, I guess I should rephrase my question by appending "and if yes, how?"

    I already downloaded that source code and all code I could find assign message list variable only from NetworkClient / NetworkServer - that's why I asked this question, in case I overlooked something.

    Anyway, I actually wrote custom messaging - I found out that all "the magic" is actually just to write int16 - id of the message and then read it and map to a delegate. (Edit: it's not "all the magic" - the Unity's NetworkConnection also buffers messages.)
     
    Last edited: Jun 24, 2017
  6. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    @Inaetaru - something definitely is going wrong. Could you strip the project and send them to me? Just pm me with zip file and explanation how I can repro this
    ?
     
  7. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    Yes, but I'll get to that later (today).
     
  8. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    Sent. The reproduction case is small, so if someone is interested, I post it also here. (Just attach the script to a game object and run Unity editor.)
     

    Attached Files:

    Deleted User likes this.
  9. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
  10. Inaetaru

    Inaetaru

    Joined:
    Aug 9, 2015
    Posts:
    16
    So, the problem is that I misunderstood some UNET concepts.

    Short answer: no, it's not possible to use Connection's message handling without NetworkClient and NetworkServer.

    Long answer: I thought that UNET is multi-layered system where each layer uses only what provides the previous one. However, that's not the case - there are only two layers. What I considered "2nd layer (Connection, Reader, Writer)" actually uses what I considered "1st layer" and (at least) "3rd layer" at the same time. Following image describes the situation:

    MyUNETUnderstanding.png

    We're not supposed to take some "layer" (for example Connection / Reader / Writer) without using "higher" layer.

    Many thanks to everyone who helped me with this issue!
     
    Deleted User likes this.