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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

WebGL - TCP Client

Discussion in 'Scripting' started by Fy-, Sep 2, 2019.

  1. Fy-

    Fy-

    Joined:
    Sep 29, 2016
    Posts:
    10
    Hey,
    I made the first version of my game and my server was made in python (with flask) and I had no problem for the WebGL version because I used UnityEngine.Networking.UnityWebRequest.

    Now for the new version I made a TCP server in python (using gevent) based on my IRCD (https://github.com/Fy-/domino/) just because it's stable (~1-year uptime on my test server).
    I would like to know if at this time there is a way to use a TCP Server for WebGL (extract of my client code below). Maybe I could use WebSocket or something else? Any information would be appreciated.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Net.Sockets;
    5. using System.Text;
    6. using System.Threading;
    7. using System;
    8.  
    9. public struct ReceivedCommand {
    10.     public string command;
    11.     public string data;
    12.  
    13.     public ReceivedCommand(string command, string data) {
    14.         this.command = command;
    15.         this.data = data;
    16.     }
    17. }
    18.  
    19. public class GameClient : SingletonMonoBehaviour<GameClient>
    20. {
    21.     public bool dev = true;
    22.     public string ipDev = "localhost";
    23.     public int portDev = 7772;
    24.     public string ipProd = "xxx.com";
    25.     public int portProd = 7771;
    26.  
    27.     public string ip {
    28.         get {
    29.             if (this.dev) {
    30.                 return this.ipDev;
    31.             }
    32.             return this.ipProd;
    33.         }
    34.     }
    35.     public int port {
    36.         get {
    37.             if (this.dev) {
    38.                 return this.portDev;
    39.             }
    40.             return this.portProd;
    41.         }
    42.     }
    43.  
    44.     private TcpClient _client;
    45.     private  Thread _clientThread;
    46.  
    47.     public Queue<ReceivedCommand> _toHandle = new Queue<ReceivedCommand>();
    48.     public Queue<string> _toSend = new Queue<string>();
    49.  
    50.     private void Start() {
    51.         this.StartClient();
    52.     }
    53.    
    54.     private void Update() {
    55.         if (this._client != null && this._client.Connected) {
    56.             if (this._toHandle.Count != 0) {
    57.                 ReceivedCommand cmd = this._toHandle.Dequeue();
    58.                 Responses.instance.OnReponse(cmd.command, cmd.data);
    59.             }
    60.             if (this._toSend.Count != 0) {
    61.                 string data = this._toSend.Dequeue();
    62.                 this.SendToServer(data);
    63.             }
    64.         }
    65.     }
    66.  
    67.     public void HandleMessage(string message) {
    68.         this.ClientLog("New message on client: "+message);
    69.         if (!message.Contains("#") && Data.me != null) {
    70.             message = SimpleEncrypt.Decrypt(Data.me.sessid, message);
    71.         }
    72.        
    73.         string[] messageSplit = message.Split('#');
    74.         string command = messageSplit[0];
    75.         string data = messageSplit[1];
    76.         if (command == "ping") {
    77.             this.SendToServer(SimpleJson.SerializeObject(new Pong()));
    78.         } else {
    79.             this._toHandle.Enqueue(new ReceivedCommand(command, data));
    80.         }
    81.     }
    82.  
    83.     public void StartClient() {
    84.         if (this._client != null) {
    85.             this.ClientLog("There is already a running client.");
    86.             return;
    87.         }
    88.         try {
    89.             this._clientThread = new Thread(new ThreadStart(this.ListenForData));
    90.             this._clientThread.IsBackground = true;
    91.             this._clientThread.Start();
    92.            
    93.             this.ClientLog("Client started");
    94.         } catch (Exception e) {
    95.             this.ClientLog("Connect exception: " + e);
    96.         }
    97.  
    98.         string sess = Store.LocalGet("sessid");
    99.         if (!string.IsNullOrEmpty(sess)) {
    100.             string data = SimpleJson.SerializeObject(new LoginSessid() { sessid = sess });
    101.             GameClient.instance.SendToServer(data);
    102.         }
    103.     }
    104.  
    105.     private void ListenForData() {
    106.         try {
    107.             this._client = new TcpClient(this.ip, this.port);
    108.             Byte[] bytes = new Byte[16384];
    109.             using (NetworkStream stream = this._client.GetStream()) {
    110.                 int length;
    111.                 while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {  
    112.                     var incommingData = new byte[length];  
    113.                     Array.Copy(bytes, 0, incommingData, 0, length);
    114.                     string serverMessage = Encoding.UTF8.GetString(incommingData);
    115.                     this.HandleMessage(serverMessage);
    116.                 }
    117.             }
    118.  
    119.         } catch (SocketException) {
    120.             this.ClientLog("Socket Error: Server not running.");
    121.         }
    122.     }
    123.  
    124.     public void SendToServer(string message) {
    125.         if (this._client == null || !this._client.Connected) {
    126.             this._toSend.Enqueue(message);
    127.             return;
    128.         }
    129.  
    130.         NetworkStream stream = this._client.GetStream();
    131.         if (stream.CanWrite) {
    132.             byte[] msg = Encoding.UTF8.GetBytes(message+"\n");
    133.             stream.Write(msg, 0, msg.Length);
    134.         } else {
    135.             this.ClientLog("Can't write.");
    136.         }
    137.     }
    138.    
    139.     public void OnDestroy() {
    140.         this.SendToServer(SimpleJson.SerializeObject(new BaseRaw() { command = "quit"}));
    141.     }
    142.  
    143.     private void Close() {
    144.         if (this._client.Connected) {
    145.             this._client.Close();
    146.             this._client = null;
    147.         }
    148.     }
    149.  
    150.     private void ClientLog(string text) {
    151.         if (this.dev) {
    152.             Debug.Log(text);
    153.         }
    154.     }
    155. }
    156.  
     
  2. jc_crash

    jc_crash

    Joined:
    Jul 30, 2019
    Posts:
    21
    Hi @Fy-

    I have recently implemented this myself. I used Websockets and implemented it through a JS plugin. The following Unity resources are most useful:

    https://docs.unity3d.com/Manual/webgl-networking.html (see the bottom)
    https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html

    and these forums will maybe help with communicating between your .jslib and Unity's C#.

    https://forum.unity.com/threads/try...etween-c-and-webgl-browser-javascript.394861/
    https://forum.unity.com/threads/send-byte-array-to-js.408091/

    Hope this helps!
     
    TrungND2 likes this.
  3. prasanna_unity488

    prasanna_unity488

    Joined:
    May 6, 2022
    Posts:
    1
    WEBGL doesn't allow threading and this results in no execution
    upload_2022-5-10_14-47-34.png
     
  4. C1wan

    C1wan

    Joined:
    May 5, 2022
    Posts:
    14
    can you please share your code or give a little bit more steps I am trying to connect a python server to a Unity WebGL build and I cant get the connection part done