Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Basic LLAPI Implementation Examples

Discussion in 'Multiplayer' started by buronix, Jan 26, 2016.

  1. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Hi All,

    Recently I start working with UNET and LLAPI and I made some basic examples of use.

    The code support Server/Client in the same Instance, also it supports Multithreading, but you still need to send and receive messages from Unity Main Thread (Update()), this is a requisite from Unity, not from my Implementation, there are queues to handle the Output messages, and some loops to listen a maximum number of messages.


    https://github.com/buronix/LLApi-Basic-Implementation

    Suggestions or Improvements are always Wellcome.
     
    TwoTen likes this.
  2. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    118
    Do you have any examples on how to use this? Seems very interesting :)
     
  3. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    TwoTen likes this.
  4. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    This has a lot of time, I have a similar but pretty advanced implementation, but the base is similar, this can work as it, basically you only need to add the classes and add the gameserver and gameclient scripts attached to objects of the scene, and in the inspector add the ExampleUser1 to the Users string array in the Gameserver script.

    This is basic for communicate between server and client, if you want to add your custom messages you need to create new subjects in the Subjects enum and add register handlers if you see the Gameclient and gameserver scripts in the awake function there is something like this :

    Code (CSharp):
    1. LLApiClient.RegisterHandler(Subjects.Connect, onClientConnection);
    this is to declare in which function you will handle the message received (in this case by the client, usually a response from the server).

    I will put you another example to send a location (Vector3) to the server, handle it in the server and send it to all the connected users.

    First you need to add 2 new subjects in the Subjects enumeration, one to send the message and another to receive the response from the server in this case :

    Code (CSharp):
    1. SendLocationRequest = 10,
    2. UserLocationResponse = 11
    then you need to declare the function to construct the message and send it to the server, for example inside the the Gameclient script.

    Code (CSharp):
    1.     private void sendPosition(Vector3 playerPosition)
    2.     {
    3. NetworkWriter writer = new NetworkWriter();
    4. writer.Write((ushort)Subjects.SendLocationRequest);
    5. writer.Write(UserID);
    6. writer.Write(playerPosition);
    7. OutputMessage outMessage = new OutputMessage(writer);
    8. LLApiClient.AddOutPutMessageToQueue(outMessage);
    9.     }
    To handle this playerposition message I created a separated and threaded class to handle it in the server, cause you dont want to block the unitythread to handle all the incoming user messages, so to handle the response you need to add in the GameServer script in the awake this:

    Code (CSharp):
    1. LLApiServer.RegisterHandler(Subjects.SendLocationRequest, ServerInfoManager.addMessageToQueue);
    and then implement the funcion in the ServerInfoManager class, to do this first you need to edit the HandleMessage function to add the new subject in this case we will create a new function called PlayerPositionRequest to handle it so:
    Code (CSharp):
    1.     private void HandleMessage(InputMessage message)
    2.     {
    3.         switch (message.MsgSubject)
    4.         {
    5.             case Subjects.LoginRequest       : LoginRequest(message); break;
    6.             case Subjects.LogOutRequest      : DisconnectRequest(message); break;
    7.             case Subjects.ServerInfoRequest  : ServerInfoRequest(message); break;
    8.             case Subjects.SendLocationRequest  : PlayerPositionRequest(message); break;
    9.         }
    10.     }
    And then implement the function :
    Code (CSharp):
    1. private void PlayerPositionRequest(InputMessage message)
    2. {
    3. string UserId= message.Reader.ReadString();
    4. Vector3 playerPosition = message.Reader.ReadVector3();
    5. NetworkWriter data = new NetworkWriter();
    6. data.Write((ushort)Subjects.UserLocationResponse);
    7. data.Write(UserId);
    8. data.Write(playerPosition);
    9. //if you dont declare a connectionId then the message will be sended to all users
    10. OutputMessage output = new OutputMessage(data);
    11. GameServer.LLApiServer.addOutPutMessageToQueue(output);
    12. }
    13.  
    and then in the client we need to handle this response from the server to do whatever we want with the user position:

    firs we declare a handler in the awake function of the client, to declare which function will handle the response, we will call the function onUserLocation, we will declare the function in the same Gameclient script :

    Code (CSharp):
    1. LLApiClient.RegisterHandler(Subjects.UserLocationResponse, onUserLocation);
    then we declare the funcion onUserLocation:

    Code (CSharp):
    1.     void onUserLocation(InputMessage message)
    2.     {
    3.         String userName = message.Reader.ReadString();
    4.         Vector3 playerPosition = message.Reader.ReadVector3();
    5.         Debug.Log("User : "+userName+" is in position "+playerPosition.ToString("F3"));
    6.         //do whatever you want with the position here
    7.     }
    So with this example you can do whatever you want, like sync the position of a player between the users, this is only an example, and very basic, but this is only to show how to communicate between client and a server with LLapi.

    Maybe there is code bugs or whatever I am writing the code in the web so be careful.
     
    Last edited: Jul 22, 2017