Search Unity

Clientrpc vs Network Message

Discussion in 'Multiplayer' started by darkmask58, Jul 11, 2015.

  1. darkmask58

    darkmask58

    Joined:
    May 9, 2015
    Posts:
    25
    Can anyone tell me in a simple way whats the difference between using a [clientrpc] or a NetworkMessage to send the strings over the network that I need to implement a chat system?
    Thanks.
     
  2. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    A clientRpc is a way to 'call a method' from a server to a client. It is one-directional. The other direction is called a command. Those only work for player object (clients with authority over it's object), as you need the authority to be able to call commands on it. Those are then used for registering user input for example. (in 5.2 clients can also be given authority to non-player objects btw).

    Network messages are a bit different in that there is no 'authoritive' part to it. It simply sends a message to a connection. You can use the builtin int and string message to send these types over the network, or make your own message type for more complex data. In order to actually receive those networkmessages, you register a callback for them on a specific message ID, which you define yourself but must be higher than Unity's internal ones.

    For my chat system, I made use of networkmessages because of the limiting factor that commands had in 5.1. What I did was, on the client side, simply send a stringmessage to the server on a messageID that the server is registered to. The server will handle this message as 'chat message received'. On the server it takes this string, applies a color to it, prefixes the username who typed the message (which is traced back by connectionID, I keep a Dictionary at runtime for all connected players) and then sends it to the clients with a custom networkmessage (string + color) on a seperate messageID. The clients are in turn registered to that messageID and simply display the message in the specified color on the screen.

    This way I can not only send player messages around, but it also allows me to easily extend functionality to display server messages (in, for example a different color) or even display errors that occurred on the server. It also prevents players from pretending to be a different player, as the displayed playername is decided on the server based on the connectionID instead of the client sending its own name.

    Hope this was all clear and helpful to you :)
     
  3. darkmask58

    darkmask58

    Joined:
    May 9, 2015
    Posts:
    25
    Yes thanks for replying. I'm making use of the network messages to send from client to server, sending a string message the same way you do and calling a clientrpc to send it back to every client, I couldn't realize how to use the NetworkServer.SendToReady to send the message just to client marked as Ready since others doesn't need to receive it.

    Any tips from which one would user less network data, or it would use the same amount of traffic?
     
  4. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    Yes sending the message back to the clients can be done with an Rpc just as well.

    As for bandwidth usage, I actually dont have a real clue how much data the Rpc's generate, but under the hood those are just NetworkMessages too (there is MsgType ID for Rpc as well). So Rpc will probably have a bit more overhead to determine the method and object that needs to be called, but I think those won't be much more than a method ID and a networkIdentity ID. Can't say this for sure though.
     
    darkmask58 likes this.
  5. darkmask58

    darkmask58

    Joined:
    May 9, 2015
    Posts:
    25
    Alright, thankyou!
     
  6. darkmask58

    darkmask58

    Joined:
    May 9, 2015
    Posts:
    25
    Do you know about the NetworkServer.SendToReady?
    http://docs.unity3d.com/ScriptReference/Networking.NetworkServer.SendToReady.html

    On the docs its used like:
    NetworkServer.Instance.SendToReady<ScoreMessage>(MyMsgTypes.MSG_SCORE, msg);

    In the monodevelop i get:
    NetworkServer.SendToReady(GameObject contextObj, short msgType, MessageBase MsgType);

    I'm not sure about what that "GameObject contextObj" means.
    Any help would be appreciated.
     
  7. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    That is weird, it seems like the docs are outdated then as it is also using 'Instance' in the statement.

    I checked the assembly to see whats up with that and apparently you can also pass in null to get similar behaviour to the SendToAll method. contextObj appears to be the gameObject (read: networkIdentity) you want to send the message to. I cant say for sure what it's used for though. I would file a bug report about the documentation for that one.

    While I was at it, Rpc's appear to have an overhead of 2 uint's and 2 shorts, which sums up to 12 bytes of overhead to determine the destination method.
     
    darkmask58 likes this.
  8. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    the context object is for object visibility rules. If a player cannot see an object, then messages for that object are not sent to the player.
     
    DizzyWascal and Vanamerax like this.