Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by stevendo · Jan 06, 2012 at 03:36 AM · multiplayerserverlagclientmmo

multiplayer customer client server code. lag issues with very straight forward code??

okay so i have a game, all i want to do is sync the position. it will have one map loaded at a time, and to syncronize the position of the player on the map

currently i am only worried about working with TWO players, not really MMO, but its a start

okay so i have written my own networking code for the client and the server. i know it may not be very secure, but its a start. anyways.

when i play locally i get NO lag. when i have a remote player playing, his game lags like mad, but locally, it does not.

i was thinking it was my code but then again, i cannot figure out why it is lagging for him.

everything works, and works like this

client sends awake command

server checks if user exists, if does not, adds to list, either way, send play players ID number

on a timer, the client will send a command saying SETPOSITION to update the players position on the server

every remote player on the client, his script on the client, calls for a GETPOSITION command on the server, the server sends back the position set by set position. this is called every x seconds on the client from the remote controlelr script

everything works, when i play locally there is no lag. there server seems to receiving the remote players commands super slow. i changed the timers to send really fast, changed the times i sleep in between commands to really small intervals.

still locally it received data much faster, i completley understand why, but my server is getting the player updates very slowly.

i also am running a timer to update the active player list incase i need to instantiate a remote player and his model. i set this on a longer running timer, every 5 seconds.

the server is receiving the data one after anotjer,

GETPLAYERLIST SETPOSITION GETPOSITION (for each player)

with out fail, though timers are set to different times.

here is the remote controller script :

[CODE]using UnityEngine; using System.Collections;

public class MyRemoteController : MonoBehaviour {
private NetworkManager networkManager; public string playerName = "My Player";

 // Remote players position and rotation
 public Vector3 MyPos;
 public Quaternion MyRot;
 
     private const string NETWORK_MANAGER = "Network Manager";
 
 private float playerUpdateTimer = 0.0f;
 private float playerStartTimer = 0.0f;
 public float playerResetTimer = 1000.0f;
 
 // Use this for initialization
 void Start () {
     // Find the network manager
     networkManager = GameObject.FindGameObjectWithTag(NETWORK_MANAGER).GetComponent<NetworkManager>();    
     if (networkManager == null)
         Debug.LogError("Cannot find the Network Manager!");
     
 }
 
 // Update is called once per frame
 void Update () {
     
     // Get data from server on this mobs position, on a timer
     if (playerUpdateTimer <= playerResetTimer)
     {    
         char[] delimiterChars = {  '|' };
         string loc = networkManager.SendGetLocation(name);
          string[] position = loc.Split(delimiterChars);

         int i = 0;
         foreach (string word in position)
         {
             if (word != "GETLOCATION")
             {
         
                 float myword = (float)System.Convert.ToSingle(word);
                 if (i==1)
                     MyPos.x = myword;
                 else if (i==2)
                     MyPos.y = myword;
                 else if (i==3)
                     MyPos.z = myword;
                 else if (i==4)
                     MyRot.x = myword;
                 else if (i==5)
                     MyRot.y = myword;
                 else if (i==6)
                     MyRot.x = myword;
             }
             i++;
         }
         playerUpdateTimer = 0.0f;
         playerStartTimer = Time.time;
     }
     else // Update Timer
     {
         playerUpdateTimer = Time.time - playerStartTimer;
     }
     
     // IS the player moving? if he is..
     if (PlayerIsMoving())
     {
         // Animate Moving
         animation.CrossFade("run");
         
         // Move - // GET THE REMOTE PLAYER INDEX AND ITS LOCATION & POSITION
         //           AT ITS INDEX
         transform.position = MyPos;
         transform.rotation = MyRot;    
         
     }
     // If he isnt moving
     else
     {
         // Animate Idle
         animation.CrossFade("idle");    
     }
 }
 
 // Has player changed location in X seconds
 // TODO
 public bool PlayerIsMoving () {
     if (true)
         return true;
     else 
         return false;
 }

} [/CODE]

here is the networjing engine i designed for the client

[CODE]using UnityEngine; using System.Collections; using System.Net.Sockets; using System.Threading; using System.Net; using System; using System.Text;

public class NetworkManager : MonoBehaviour { private GameManager gm;

 public string ServerAddress = "127.0.0.1";
 public int ServerPort = 3000;
 public int ThreadSleepTime = 12;
 
 private TcpClient client;
 private IPEndPoint serverEndPoint;
 private NetworkStream clientStream;
 
 private const string GAME_MANAGER = "Game Manager";
 
 // Use this for initialization
 void Start () {
     // Find the game manager
     gm = GameObject.FindGameObjectWithTag(GAME_MANAGER).GetComponent<GameManager>();    
     if (gm == null)
         Debug.LogError("Cannot find the Game Manager!");
     
     // Create our client, endpoint, and then connect
     client = new TcpClient();
     serverEndPoint = new IPEndPoint(IPAddress.Parse(ServerAddress), ServerPort);
     client.Connect(serverEndPoint);
     
     // Setup our stream..
     clientStream = client.GetStream();
 }
 
 // Update is called once per frame
 void Update () {
 
 }
 
 // Close the connection
 public void CloseConnection (){
     client.Close();
 }
 
 // Send Data to server
 public void SendDataToServer (string MyString){
             
     ASCIIEncoding encoder = new ASCIIEncoding();
     byte[] buffer = encoder.GetBytes(MyString);
     
     clientStream.Write(buffer, 0 , buffer.Length);
     clientStream.Flush();
     
 }
 
 // Send the Awake Command
 // Return True if we successfully connect
 public bool SendServerAwake (){
     try {
             MyPlayerController MYPC    = gm.GetPlayerController().GetComponent<MyPlayerController>();
             string MyString = "AWAKE" + MYPC.playerName +"@";
                         
             ASCIIEncoding encoder = new ASCIIEncoding();
             byte[] buffer = encoder.GetBytes(MyString);
             
             clientStream.Write(buffer, 0 , buffer.Length);
             clientStream.Flush();
             Thread.Sleep(ThreadSleepTime);
         
             // Wait for the player list return
             byte[] message = new byte[4096];
             int bytesRead;
             
             bytesRead = 0;
     
             //blocks until a client sends a message
             bytesRead = clientStream.Read(message, 0, 4096);
             
             //message has successfully been received
             MyString = encoder.GetString(message, 0, bytesRead);
         
         
             char[] delimiterChars = {  '|' };
             string[] players = MyString.Split(delimiterChars);
             MYPC.myPlayerIndex = System.Convert.ToInt32(players[1]);
     
             
             return true;
     }
     catch {
     
             return false;
     }
 }
 
 // Send the Get Player List Command
 public string SendGetPlayerList (){
     string MyString = "GETPLAYERLIST@";        
     ASCIIEncoding encoder = new ASCIIEncoding();
     byte[] buffer = encoder.GetBytes(MyString);
     
     clientStream.Write(buffer, 0 , buffer.Length);
     clientStream.Flush();
     
     // Wait for the player list return
     byte[] message = new byte[4096];
     int bytesRead;
     
     bytesRead = 0;

     //blocks until a client sends a message
     bytesRead = clientStream.Read(message, 0, 4096);
     
     //message has successfully been received
     MyString = encoder.GetString(message, 0, bytesRead);
     
     Thread.Sleep(ThreadSleepTime);
     
     return MyString; // Return the player list
 }
 
 // Send the Get Player Location Command
 public string SendGetLocation (string playerName){
     
     string MyString = "GETLOCATION" + playerName  +"@";        
     ASCIIEncoding encoder = new ASCIIEncoding();
     byte[] buffer = encoder.GetBytes(MyString);
     
     clientStream.Write(buffer, 0 , buffer.Length);
     clientStream.Flush();
     
     // Wait for the player list return
     byte[] message = new byte[4096];
     int bytesRead;
     
     bytesRead = 0;

     //blocks until a client sends a message
     bytesRead = clientStream.Read(message, 0, 4096);
     
     //message has successfully been received
     MyString = "";
     MyString = encoder.GetString(message, 0, bytesRead);
     
     Thread.Sleep(ThreadSleepTime);
     
     return MyString; // Return the player list
 }

 // Send the Set Player Position Command
 // Return True if we successfully send
 public bool SendServerLocation (){
     try {
             MyPlayerController MYPC    = gm.GetPlayerController().GetComponent<MyPlayerController>();
             string MyString = "SETLOCATION" + MYPC.playerName + "|" + MYPC.transform.position.x + "|" + MYPC.transform.position.y + "|" + MYPC.transform.position.z
                                              + "|" + MYPC.transform.rotation.x + "|" + MYPC.transform.rotation.y + "|" + MYPC.transform.rotation.z +"@";
                         
             ASCIIEncoding encoder = new ASCIIEncoding();
             byte[] buffer = encoder.GetBytes(MyString);
             
             clientStream.Write(buffer, 0 , buffer.Length);
             clientStream.Flush();
     Thread.Sleep(ThreadSleepTime);;
             
             return true;
     }
     catch {
     
             return false;
     }
 }

} [/CODE]

and here is the class i designed, a multi threaded server in c#

[CODE]using System; using System.Text; using System.Net.Sockets; using System.Threading; using System.Net; using System.Collections.Generic;

namespace EuphonicServer { class MyServer {

     private TcpListener tcpListener;
     private Thread listenThread;
     private IPEndPoint serverEndPoint;

     List<string> playerlist = new List<string>();
     List<string> playerlocation = new List<string>();
     
     public MyServer()
     {

         this.tcpListener = new TcpListener(IPAddress.Any,3000);
         this.listenThread = new Thread(new ThreadStart(ListenForClients));
         this.listenThread.Start();
     }

     private void ListenForClients()
     {
         this.tcpListener.Start();

         while (true)
         {
             //blocks until a client has connected to the server
             TcpClient client = this.tcpListener.AcceptTcpClient();

             //create a thread to handle communication 
             //with connected client
             Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
             clientThread.Start(client);
         }
     }

     private void HandleClientComm(object client)
     {
         TcpClient tcpClient = (TcpClient)client;
         NetworkStream clientStream = tcpClient.GetStream();

         byte[] message = new byte[4096];
         int bytesRead;

         while (tcpClient.Connected)
         {
             bytesRead = 0;

             try
             {
                 //blocks until a client sends a message
                 bytesRead = clientStream.Read(message, 0, 4096);
             }
             catch
             {
                 //a socket error has occured
                 break;
             }

             if (bytesRead == 0)
             {
                 //the client has disconnected from the server
                 break;
             }

             //message has successfully been received
             ASCIIEncoding encoder = new ASCIIEncoding();
             string TheString = encoder.GetString(message, 0, bytesRead);

             // Incase we received more that we are supposed to, check
             char[] delimiterCharz = { '@' };
             string[] positions = TheString.Split(delimiterCharz);
             string MyString = positions[0];


             /// PLAYER AWAKE FUNCTION
             /// ---------------------
             /// Add the player to the game world
             if (MyString.Substring(0, 5) == "AWAKE")
             {
                 // Remove Protocol String, MyString will now contain argument
                 MyString = MyString.Replace("AWAKE", "");

                 bool playerExists = false;

                 int i = 0;
                 /* Is the player already in the game world and get the index */
                 foreach (string player in playerlist)
                 {
                     if (player == MyString){
                         playerExists = true;
                         break;
                     }
                     else
                         i++;
                 }

                 // add player to the game world
                 if (!playerExists)
                 {
                     playerlist.Add(MyString);
                     playerlocation.Add("0|0|0|0|0|0");
                     i++;
                 }
                 
                     // Send the player the players index
                     byte[] buffer = encoder.GetBytes("AWAKE|" + i);
                     clientStream.Write(buffer, 0, buffer.Length);
                     clientStream.Flush();
                 
                     Console.WriteLine("AWAKE: " + MyString);
             }

             /// GET PLAYER LIST
             /// ---------------
             /// Send the client the current player list
             else if (MyString.Substring(0, 13) == "GETPLAYERLIST")
             {
                 string plist = "GETPLAYERLIST";

                 // Build a player list string
                 foreach (string player in playerlist)
                 {
                     plist = plist + "|" + player;
                 }
         
                     // Send the player list string we have built
                     byte[] buffer = encoder.GetBytes(plist);
                     clientStream.Write(buffer, 0, buffer.Length);
                     clientStream.Flush();

                 Console.WriteLine(plist);
             }

             /// GET PLAYER LOCATION
             /// ---------------
             /// Send the client the requested players location
             else if (MyString.Substring(0, 11) == "GETLOCATION")
             {
                 // Remove Protocol String, MyString will now contain argument
                 MyString = MyString.Replace("GETLOCATION", "");

                 // Construct the player location string
                 string plist = "GETLOCATION";

                 int i = 0;
                 foreach (string player in playerlist)
                 {
                     if (player == MyString)
                         plist = plist + "|" + playerlocation[i];

                     i++;
                 }

                 // Send the player list string we have built
                 byte[] buffer = encoder.GetBytes(plist);
                 clientStream.Write(buffer, 0, buffer.Length);
                 clientStream.Flush();

                 Console.WriteLine(MyString + ": " + plist);
             }

              /// SET PLAYER LOCATION
             /// ---------------
             /// Set the requested players position
             else if (MyString.Substring(0, 11) == "SETLOCATION")
             {
                 // Remove Protocol String, MyString will now contain argument
                 MyString = MyString.Replace("SETLOCATION", "");

                 char[] delimiterChars = { '|' };
                 string[] position = MyString.Split(delimiterChars);

                 string myname = position[0];
                 string myposx = position[1];
                 string myposy = position[2];
                 string myposz = position[3];
                 string myrotx = position[4];
                 string myroty = position[5];
                 string myrotz = position[6];

                 // Set the players location

                 int i = 0;
                 foreach (string player in playerlist)
                 {
                     if (player == myname)
                         playerlocation[i] = myposx + "|" + myposy + "|" + myposz + "|" +myrotx + "|" + myroty + "|" + myrotz ; 

                     i++;
                 }

                 Console.WriteLine("SETLOCATION: " + MyString);
             }
         }
         
         Console.WriteLine("Client Disconnected");
         tcpClient.Close();
     }
 }

}[/CODE]

my connection is fast enough to run apache and server websites with ease. why is my server getting this informaton so slowly? what can i do to prevent this lag?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Character Animation Lags in Multiplayer 2 Answers

Unity networking tutorial? 6 Answers

Missing line renderer in multiplayer? 0 Answers

indie db hosting woes 1 Answer

Would it be possible for every person to host the server.... And yet no one. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges