Search Unity

Best HTTP Released

Discussion in 'Assets and Asset Store' started by BestHTTP, Sep 11, 2013.

  1. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    @vfilho , a few messages up reported the same issue. No response from @BestHTTP

    Hard to fathom what could be causing that.
     
  2. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    BTW, can you try switching to Unity's web request just to see if it's behavior is different under TestFlight than BestHTTP? Would be good to know if it's a BestHTTP issue specifically or not.
     
  3. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @vfilho @sandcastles @nsxdavid

    Sorry, the the forum engine reminded me about the last message only today... :/

    As the plugin implemented in pure c#, it could be something in the lower layers. For example, XCode 8.3 seems to have a compiler bug that prevents the plugin to decompress gzipped data.

    First, I would suggest to try out setting the ConnectTimeout to zero, it uses less logic, and we can see what happens:
    Code (CSharp):
    1. HTTPManager.ConnectTimeout = TimeSpan.Zero;
     
  4. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    @BestHTTP Heyya, I've got a interesting problem I'm trying to track down...

    BestHTTP seems to double the expected latency. I have a testwith a simple web service that merely pings back a text response.

    The first call is slow due to opening the connection and SSL negotaiation.

    Subsequent calls, however, are often take double as long as you'd expect.

    I setup a network conditioner to induce 300ms of latency on up and down, as a test.

    In chrome, I'll get a response on (not first request) of about 635ms. About what one would expect.

    On BestHTTP, I'll get ~1300ms doing the exact same thing.

    This is causing lots of issues for our mobile title... in the US it's no biggie, but our overseas users already have latencies in those range (speed of light and all that) and it's doubling what it should be. And that's not working well at all.

    Any idea what's going on here?
     
  5. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    ... well, after much digging, I did find the issue:

    When BestHTTP creates a TCP/IP client, it does so defaulting to using the Nagle algorithm. Which of course introduces the unnecessary delay in sending web requests. One can fix this by setting NoDelay to true.

    The problem, however, is that clients are created as needed. So there seems to be no way to control this without modifying BestHTTP code. I'd rather one could configure this without having to modify the plugin itself.
     
  6. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @nsxdavid

    There's only one place where a TcpClient is created, or you can modify the TcpClient.cs itself.

    Another delay can come from how callbacks are dispatched. By default the plugin uses Unity's Update event to check for completed requests, and will call the callbacks.
    Depending on the FPS, it can add more or less delay.
     
  7. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    Right, I did change TcpClient.cs, but I don't want to do that. Because if you do any updates, now I have to remember I made that change and reapply it each time. Rather you made a way to specify that.

    I did note the Update()-dependent dispatch, and felt that was pretty icky but not sure what to do about it. Hoping you had an idea.
     
  8. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @nsxdavid

    I will try to find out something that makes both of us happy.

    There's a built-in way to avoid the frame-delay. You can configure the HTTPUpdateDelegator to use a thread instead of the Update event. This way, the delay is minimized, but you have to deal with thread synchronization.
    You have to place these somewhere in your startup code, before any other BestHTTP call:
    Code (CSharp):
    1. HTTPUpdateDelegator.IsThreaded = true;
    2. HTTPUpdateDelegator.ThreadFrequencyInMS = 1;
    ThreadFrequencyInMS is 100 by default, you can adjust it for your needs and taste.
     
  9. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    365
    Yeah I'm not sure that's what I need to be looking at. Obviously it depends on the device, but we're generally rocking between 30 and 60fps. So at worst Update frequency might account for a 15-33ms delay on bad beats.

    Right now, with Nagel off, my ping test on my home internet to the game server is getting 66ms steady. But one out of 20 or so will get something like twice that I wonder if that's a TCP/IP resend or something. But I'm still wondering if there's something internal that can cause a near constant doubling of the round-trip time on the client side. It's hard to get much visibility into these things.
     
  10. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @nsxdavid

    Sent a link to an updated package with a new feature to turn TcpNodelay on/off.

    The plugin will try to reuse the TCP connection as much as it can, but the server still can close it after a specified time and/or request count. The plugin will also close the connection after some idle time (20 sec by default - HTTPManager.MaxConnectionIdleTime).

    Some additional notes on latency:
    1.) The plugin is in pure c#, while a browser's critical code-path is a compiled, native code.
    2.) The plugin also does the TLS/SSL encryption/decryption in c# too. BouncyCastle bundled with the plugin, you can turn off and go back to the mono implementation by setting HTTPManager.UseAlternateSSLDefaultValue to false.
    3.) The plugin must work with managed strings and buffers, all the safety added by the framework.
    4.) Eventually, all data must be passed to a native function, data must be pinned(it will mess with the GC) and marshaled.
    5.) Request processing done on a background thread. It's quite possible that the queuing up job will not start it immediately.
    6.) If the response is sent gzipped, the plugin must decompress it.
    7.) GC pauses
     
  11. Liam-C

    Liam-C

    Joined:
    Mar 6, 2017
    Posts:
    3
    @BestHTTP

    I just bought this package (pro version) yesterday and it's great. So far i've replaced my SignalR implementation based off a bad .NET 3.5 client port with the BestHTTP version and it works much better. Overall I'm incredibly happy with the package, but i have one small request.

    In the IHeartbeat.OnHeartbeatUpdate method at line 1099 of Connection.cs you use UnityEngine.Debug.Log instead of HTTPManager.Logger, so the logging won't go through my NLog implementation of the ILogger interface. This particular message occurs several hundred times in the ~30 seconds that the connection tries to reconnect for.

    I'm targeting very low-end hardware and can't afford the overhead from the extra logging, string concatenation and file i/o. Also, the arguments should be passed into a logging method so that the concatenation can be skipped if the logger is configured to skip this Loglevel.

    This is a non-urgent issue that I could fix myself, but I don't want to maintain a list of changes that have to be reapplied each time I download a BestHTTP update. Could you please include this change in your next release? I've only used the SignalR feature so far, so i'm not sure if this is the only direct usage of the UnityEngine.Debug.Log api.
     
  12. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @Liam-C

    Thanks, that should be a Logger.Warning. It shouldn't be called so much, either. I will check it out.

    Where the logging would be too much overhead, I'm usually checking against the log level, to avoid the call completely.:
    Code (CSharp):
    1. if (HTTPManager.Logger.Level <= Logger.Loglevels.Warning)
    2.   HTTPManager.Logger.Warning("SignalR Connection", this.ReconnectStarted.ToString() + " " + this.ReconnectStartedAt.ToString() + " " + NegotiationResult.DisconnectTimeout.ToString());
    (You can replace that logging line with these two.)

    A logging method would add additional overhead when all the conditions are met to log. Nonetheless, it would be a much cleaner, readable solution.
     
  13. Honeywell

    Honeywell

    Joined:
    May 15, 2017
    Posts:
    1
    Hi I'm using BestHTTP (pro). I've written a piece of code to receive messages from signalr hub. It works well in my dev machine. When I deploy it in a test environment, it fails with the below error.
     

    Attached Files:

  14. reddy36996

    reddy36996

    Joined:
    Jan 10, 2016
    Posts:
    19
    I faced the same issue while back. Actually i was trying to connect to signalr server hosted locally using "https" instead of "http" in base url. After changing it to "http", it started working
     
  15. mitchmeyer1

    mitchmeyer1

    Joined:
    Sep 19, 2016
    Posts:
    21
    Having a problem since upgrading to Unity 5.5.3 with Android. WebGL and iOS work perfectly but for Android my callback function's response object is null. Here is my function. Has anyone had this problem?

    public void SignIn(string username, string password){

    string url =urlPrefix+"/api/"+version+"/sign_in.json";
    print ("Signing in to '" + url+"'");
    if (username == null || username.Length == 0)
    del.RequestError ("Please fill out the username field!");
    else if (password == null || password.Length == 0)
    del.RequestError ("Please fill out the password field!");
    else {
    this.username = username;
    this.password = password;
    HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post,OnSignInRequestFinished);
    request.AddField("email",username);
    request.AddField("password", password);
    request.Send();
    }
    }

    void OnSignInRequestFinished(HTTPRequest request, HTTPResponse response)
    {
    try
    {
    print ("RESPONSE IS NULL? "+(response == null).ToString());
    print ("RESPONSE: "+response.ToString());
    if (response.IsSuccess) {
    data.currentStudent = Student.CreateFromJSON (PeelOffDataJsonWrapper(response.DataAsText));
    hasRequestInProgress = false;
    if (data.currentStudent.IsValid()) {
    del.RequestSuccess ();
    } else {
    del.RequestError ("Incoming login data is corrupt. \n Check your firewall!");

    }

    } else {
    hasRequestInProgress = false;
    del.RequestError (response.Message);
    }
    }

    catch (Exception e)
    {
    hasRequestInProgress = false;
    var message = e.Message;
    del.RequestError (message);
    }
    }


    Thanks
    -Mitch
     
  16. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @Honeywell

    As @reddy36996 noted, if you try to connect to a HTTP endpoint using HTTPS, you will receive the very same error.
     
  17. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @Honeywell

    The errorlog.txt you attached is from a windows build. Under WebGL it would run on a completely different code path.
     
  18. gschemmel

    gschemmel

    Joined:
    Mar 11, 2015
    Posts:
    4
    Is there a change log for 1.10.0?
     
  19. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @gschemmel

    Updated my first post, but adding it here too.

    It has a public API change, download progress API is long based instead of int. And WP8 support also removed.

    1.10.0 (2017.05.05)
    • General
      • Removed support for Windows Phone 8
      • [New Feature] HTTPManager and HTTPRequest has a new property 'TryToMinimizeTCPLatency' to turn on/off TCP NoDelay
      • [New Feature] A new Form type 'RawJson' to send the fields added with AddField jon encoded
      • [Improvement] Added DefaultCertificationValidator to the HTTPManger
      • [Improvement] Improved compatibility with Unity 2017.1
      • [Improvement] Now the plugin capable to download files larger than 2 GB (Thanks goes to Daniel @ present4D)
      • [Bugfix] Accessing streaming assets now possible under WebGL builds
      • [Bugfix] Fixed a sneaky bug where the HTTPUpdateDelegator unloaded in builds
    • Socket.IO
      • [Improvement] Sockets now have an Id property generated the same as in the JS Socket.IO lib.
     
    gschemmel likes this.
  20. lancepriebe

    lancepriebe

    Joined:
    Apr 24, 2016
    Posts:
    3
    Ok, I am lost with json, objects and socket.io. I am attempting to create an object from a class using the arg[0].

    My socket.io is sending:

    Code (CSharp):
    1. io.emit("Login",{ PlayerId:"PLAYER1", DisplayName:"Name1", Level:1, Inventory: [{ ItemId:1,Qty:1},{ ItemId:1,Qty:1}], Coins:100 });
    How do I convert this to a class in Unity?
     
  21. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @lancepriebe

    Here is an example:
    Code (CSharp):
    1. class PlayerInventory {
    2.   public int ItemId;
    3.   public int Qty;
    4. }
    5.  
    6. class Player {
    7.   public string PlayerId;
    8.   public string DisplayName;
    9.   public int Level;
    10.   public int Coins;
    11.   public List<PlayerInventory> Inventory;
    12.  
    13.   public override string ToString() {
    14.     return string.Format("[Player PlayerId: {0}, DisplayName: {1}, Level: {2}, Coins: {3}, Inventory: {4}]", this.PlayerId, this.DisplayName, this.Level, this.Coins, this.Inventory != null ? this.Inventory.Count : -1);
    15.   }
    16. }
    17.  
    18. SocketManager io = new SocketManager(new Uri("http://localhost:3000/socket.io/"));
    19.  
    20. // Step 1: Use a more advanced json encoder. Using it, we can pass an object to the Emit function, it will encode
    21. //  it as json.
    22. io.Encoder = new BestHTTP.SocketIO.JsonEncoders.LitJsonEncoder();
    23.  
    24. // Step 2: Setup the encoder. The PlayerObject class contains int field, but LitJson will decode them as doubles.
    25. //  We can register a function to be able to convert from double to int.
    26. JsonMapper.RegisterImporter<double, int>((input) => (int)(input + 0.5));
    27.  
    28. io.Socket.On("Login", (socket, packet, args) => {
    29.     // Do the conversion
    30.     Player player = ConvertTo<Player>(args[0]);
    31.  
    32.     Debug.Log(player);
    33.   });
    34.  
    35. static T ConvertTo<T>(object obj) {
    36.   JsonWriter writer = new JsonWriter();
    37.   JsonMapper.ToJson(obj, writer);
    38.  
    39.   return JsonMapper.ToObject<T>(new JsonReader(writer.ToString()));
    40. }
     
  22. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Hi,

    I've read the reviews for this plugin and it seems promising.

    Anyway, I literally just installed the plugin just then in Unity, and I've gotten these errors:



    Thanks
     
  23. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    Hmm, I would try to delete the /Assets/Best HTTP (Pro)/ folder then redownload&inport the package. It looks Unity messed up something.
    You can try to import it into a very new project too to see whether the errors remain.
     
  24. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Thanks for the fast reply. Actually I managed to fix it. It seems that I had my own Strings.cs file, and it was referring to that, and not the one inside the plugin. I simply just changed my Strings classname, then re-imported the plugin so now it works properly.
     
  25. MBargiel

    MBargiel

    Joined:
    Oct 29, 2016
    Posts:
    2
    We have been using Best HTTP Pro for over a year now and consider this pretty solid software. Recently though, in one of our games with a backend, we noticed in the server logs that about 0.5% of connections are aborted. We figured that this was due to a backend request that was attempting to save on pause/quit, and which would be aborted by the OnApplicationQuit logic.

    On Android, we can prevent Unity from quitting and then force a quit once the final saves are complete. However on iOS we cannot do that. When the app is closed, Unity cannot stall for time. However we can register for background execution to complete tasks like this. (See https://developer.apple.com/library.../BackgroundExecution/BackgroundExecution.html)

    Do you have any plans to use native implementations for the HTTP connections at some point? If you wrapped NSURLSessions instead (optionally or not, as you see fit), it would be possible to support background execution and allow these requests to survive app shutdown. In fact, this wouldn't need to be a specific case for app termination, since all NSURLSessions can be registered for background execution. As per the Apple documentation:

     
    Last edited: May 18, 2017
    OlivierPons likes this.
  26. mitchmeyer1

    mitchmeyer1

    Joined:
    Sep 19, 2016
    Posts:
    21
    I get the response object as null in the callback function when the url cant be reached (fake url or no internet). Is this how the library is designed? Its very consistent in any new project I create in Unity 5.5.3
     
  27. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Given that I have this code on the server:

    socket.emit('socketID', {id: socket.id});​

    How would I make it so that Unity can read this value? I tried looking at the documents, and searching in this thread, but the documents are vague and the example earlier didn't work for me.

    manager.Socket.On("socketID", OnSocketId);
    void OnSocketId(Socket socket, Packet packet, params object[] args)
    {
    // I want to print "id" from the JSON object​
    }​
    And lately my Unity has been crashing so often ever since the new update. I don't know if BestHTTP is causing this or not. Any of you guys also experiencing this, or is it just me?


    Edit:

    Again, managed to figure this out on my own. I had to delete the "params" word in the method parameters. I'm not sure why that was there, when I had copied that from the documents.

    Edit 2:

    If I were to send an int from the server, how would I use that in the C# client?
     
    Last edited: May 19, 2017
  28. melefans

    melefans

    Joined:
    Aug 1, 2016
    Posts:
    36
    @BestHTTP
    upgrade latest BestHttp pro Edition (From Unity Asset Store)
    My Unity Version : 5.5.0p4
    Runtime error (server closes the connection causing an error)

    An WebSocket error occured: TCP Stream closed unexpectedly by the remote server

    ErrorDesc: Request Finished with Error! Exception: TCP Stream closed unexpectedly by the remote server at BestHTTP.WebSocket.Frames.WebSocketFrameReader.ReadByte (System.IO.Stream stream) [0x0000f] in /kernel/codes/Client/Unity/Assets/Plugins/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs:140
    at BestHTTP.WebSocket.Frames.WebSocketFrameReader.Read (System.IO.Stream stream) [0x00004] in /kernel/codes/Client/Unity/Assets/Plugins/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs:65
    at BestHTTP.WebSocket.WebSocketResponse.ReceiveThreadFunc (System.Object param) [0x00016] in /kernel/codes//Client/Unity/Assets/Plugins/BestHTTP/WebSocket/WebSocketResponse.cs:334
    UnityEngine.Debug:Log(Object)
    GKLog:printf(String) (at Assets/Plugins/FrameWork/Uitls/GKLog.cs:22)
    GK.Net.GKWebSocket:printf(String) (at Assets/Plugins/FrameWork/Net/GKWebSocket/GKWebSocket.cs:261)
    GK.Net.GKWebSocket:OnErrorDesc(WebSocket, String) (at Assets/Plugins/FrameWork/Net/GKWebSocket/GKWebSocket.cs:380)
    BestHTTP.WebSocket.WebSocket:OnInternalRequestCallback(HTTPRequest, HTTPResponse) (at Assets/Plugins/BestHTTP/WebSocket/WebSocket.cs:319)
    BestHTTP.HTTPRequest:CallCallback() (at Assets/Plugins/BestHTTP/HTTPRequest.cs:1251)
    BestHTTP.ConnectionBase:HandleCallback() (at Assets/Plugins/BestHTTP/Connections/ConnectionBase.cs:171)
    BestHTTP.HTTPManager:OnUpdate() (at Assets/Plugins/BestHTTP/HTTPManager.cs:611)
    BestHTTP.HTTPUpdateDelegator:Update() (at Assets/Plugins/BestHTTP/HTTPUpdateDelegator.cs:163)

    The old version is working. callback OnClose()
     
    Last edited: May 19, 2017
  29. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @mitchmeyer1

    Yes, it's the intended behavior. The response is not-null only, when reading back the response was successful.
    Checking for errors you should use the request's State property:
    Code (CSharp):
    1. Uri uri = new Uri("http://httpbin.org/get");
    2.  
    3. HTTPRequest request = new HTTPRequest(uri, (req, resp) =>
    4. {
    5.     switch (req.State)
    6.     {
    7.         // The request finished without any problem.
    8.         case HTTPRequestStates.Finished:
    9.             if (resp.IsSuccess)
    10.             {
    11.                 Debug.Log("Request Finished Successfully! Response: '" + resp.DataAsText + "'");
    12.             }
    13.             else // Internal server error?
    14.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    15.                                                 resp.StatusCode,
    16.                                                 resp.Message,
    17.                                                 resp.DataAsText));
    18.             break;
    19.  
    20.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    21.         case HTTPRequestStates.Error:
    22.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    23.             break;
    24.  
    25.         // The request aborted, initiated by the user.
    26.         case HTTPRequestStates.Aborted:
    27.             Debug.LogWarning("Request Aborted!");
    28.             break;
    29.  
    30.         // Connecting to the server is timed out.
    31.         case HTTPRequestStates.ConnectionTimedOut:
    32.             Debug.LogError("Connection Timed Out!");
    33.             break;
    34.  
    35.         // The request didn't finished in the given time.
    36.         case HTTPRequestStates.TimedOut:
    37.             Debug.LogError("Processing the request Timed Out!");
    38.             break;
    39.     }
    40. });
    41.  
    42. request.Send();
     
    mitchmeyer1 likes this.
  30. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    If you just send the int itself (socket.Emit('event', intValue)), you can use the Convert.ToInt32 call, or double-cast it: (int)(double)args[0].
     
  31. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Thank you.

    Also I figured out why my Unity was freezing. I had to disconnect from all the sockets and managers when I exited the application. Before I didn't do that, and when I closed the game, the "game" was technically still running.
     
  32. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    Yeah, Unity keeps threads running in the Editor even after the application is stopped.
     
  33. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    What's the difference between a Socket and a SocketManager? From the documents, I saw no direct use of a Socket object, except in some functions, but never did I see any direct usage for a Socket object instantiated from a manager.

    Edit: My premise is that the client will be connected to multiple different servers at once (i.e: Chat Server, Game Server, News Server), so in that case, would I require 3 SocketManagers?
     
  34. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    A Socket is bound to a Socket.IO namespace. The default namespace is the root '/' namespace.
    The SocketManager manages all the Sockets, while a Socket is responsible to send events to the server, and handle incoming ones.

    When you used socketManager.Socket.On(...), you used the socket manager to get the root socket (.Socket), and register an event handler (.On).
     
  35. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Ah now that makes sense. So it is true that Sockets created from a SocketManager can only be "based" upon the SocketManager's URI? (E.g: Root Socket = "/", SocketX = "/path/", SocketY = "/foo/")

    So if you were to be connected to two different servers at once, you would have to have multiple unique Socket Managers?
     
  36. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    To connect to a namespace the plugin will send a 'connect' packet to the server, URI paths are not involved here.
    One SocketManager can connect to one server, but it can manage multiple namespaces. So yes, for different servers you have to create multiple SocketManagers.
     
  37. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @MBargiel

    On iOS when the app goes to background there's still enough time to send requests.
    The plugin itself will abort a request only when the OnDisable or OnApplicationQuit events are called on the HTTPUpdateDelegator. When this happens it's still possible to prevent plugin shutdown by writing an HTTPUpdateDelegator.OnBeforeApplicationQuit event handler.

    While it would be possible to use native functions on iOS (and on other platforms too), i have no intention yet to write native handlers too.
     
  38. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
  39. melefans

    melefans

    Joined:
    Aug 1, 2016
    Posts:
    36
    @BestHTTP
    I can not find the version number, I see git update log, is October 22, 2015
     
  40. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @melefans

    That's really old! :) It can be 1.9.5. There were a lot of changes for WebSocket since.
    You can turn on a more verbose logging:
    Code (CSharp):
    1. BestHTTP.HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.All;
    Maybe it will log out something useful.

    Or, if it's possible you can send a repro project or the url to test it out myself.
     
  41. MBargiel

    MBargiel

    Joined:
    Oct 29, 2016
    Posts:
    2
    Thanks for the response. We'll look into OnApplicationPause, and consider using the OnBeforeApplicationQuit callback to prevent cancelling requests triggered from OnApplicationPause as a safety.

    By the way, I'm not too sure how best to use OnBeforeApplicationQuit. Even if we were to prevent plugin shutdown with it, wouldn't there be a risk that the connections be brutally closed when the app itself shutdown? Is there a way to attempt gracefully shut down the plugin after originally preventing its shutdown, aside from calling Application.Quit again (which wouldn't work on iOS, I think) once we know the requests are complete?
     
  42. melefans

    melefans

    Joined:
    Aug 1, 2016
    Posts:
    36
    @BestHTTP
    Thanks for the response , I try to change loglevel and get more information.
    But I still can not find the cause of the error.
    upload_2017-5-20_10-21-53.png
     
  43. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    How does one send an object (multiple variables) from a Unity Client (socket.io) to the Node.js Server (socket.io)?

    I know that the code required to send data to the server is this:

    manager.Socket.emit("login", Callback, username);

    But when I try to something like this:

    manager.Socket..emit("login", Callback, username, level, exp, client);

    The node.js server only prints "username" as its data, given this code:

    socket.on('login', function (data, callback) {
    console.log('data:', data); // prints out only username, and does not include level, exp and client
    }


    Edit: I managed to solve this, but I am not sure about the efficiency of my solution. I created a new Message class in C#, instantiated it with my values, called JsonUtility.ToJson to convert it to a JSON string, then pass that string over Socket.emit. I then parse that string on the server using
    JSON.parse and then access that data.

    Also as far as I am concerned, you can only send the first argument (if you have multiple) when you use Socket.emit. Though I am not 100% sure.
     
    Last edited: May 22, 2017
  44. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    @BestHTTP

    I noticed that you posted some code a while ago which addresses my problem that I had. I was wondering how you would use this? (i.e: where would this code go, and how would you call Socket.emit in relation to using this extension method, especially with a callback)


    Edit: I have mangaed to make it work by having a class like this:


    namespace MageBall.Extensions
    {
    public static class Extensions
    {

    public static Socket Emit(this Socket socket, bool boolean,
    string eventName, JSONObject jsonobj)
    {
    Debug.Log("Extension");
    JSONObject pack = new JSONObject(JSONObject.Type.ARRAY);
    pack.Add(eventName);
    pack.Add(jsonobj);

    Packet packet = new Packet(TransportEventTypes.Message,
    SocketIOEventTypes.Event,
    socket.Namespace,
    pack.ToString(),
    0,
    0);

    (socket.Manager as IManager).SendPacket(packet);

    return socket;
    }


    }

    }

    And then calling this code to use the extension method:

    xxx.Socket.Emit(true, eventName, jsonObject);

    I had to put in an extra argument, because the compiler would default to the non-extension method version of Socket#Emit(). So now it recognises the extended Emit() version, and does print "Extension" in the log.

    I tried putting in Callback in the extension method, but I've had no luck in getting it to work.
     
    Last edited: May 22, 2017
  45. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @MBargiel

    You can add a callback to OnBeforeApplicationQuit and null it out when called. Then when appropriate, you can call HTTPManager.OnQuit() to shut the plugin down.

    There are always a chance that the underlying (mobile) OS will close the application, but normally there's plenty of time to send a request.
     
  46. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @melefans

    Hmm, that's closed quite early. It looks that the server forcefully closed the connection, but don't know why. What you are using on the server side?
    Is it possible to send me the websocket endpoint so I can debug it out? You can send it to besthttp@gmail.com.
     
  47. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,401
    @ShotgunJed

    You don't have that custom emit (yet). You can send an array of objects right with the default Emit:
    Code (CSharp):
    1. manager.Socket.Emit("multipleParams", multipleParamsCallback, "BestHTTP", 99, 198, "Unity Client");
    2.  
    3. private void multipleParamsCallback(Socket socket, Packet packet, object[] args) {
    4.   Debug.Log(args[0].ToString());
    5. }
    Server code:
    Code (CSharp):
    1. socket.on('multipleParams', function (username, level, exp, client, callback) {
    2.     console.log("%s %d %d %s", username, level, exp, client);
    3.  
    4.     callback("Received!");
    5. });
    This way you can avoid additional encoding/decoding, and you can use both the server and client as you would do normally with the JS client.
     
  48. ShotgunJed

    ShotgunJed

    Joined:
    May 18, 2017
    Posts:
    9
    Thank you very much!

    I quickly tried that code you posted and it worked perfect. I never knew that it was so simple to just add in extra arguments on the server side.

    I had no idea what I was doing earlier with all those Extended methods.
     
  49. melefans

    melefans

    Joined:
    Aug 1, 2016
    Posts:
    36
    @BestHTTP
    hi , my test example has been sent to your mailbox.
     
    Last edited: Mar 10, 2018
  50. littlstarsunny

    littlstarsunny

    Joined:
    Apr 12, 2017
    Posts:
    7
    @BestHTTP

    Our app sometimes experiences connection timeout errors on requests. I know the general strategy is to increase ConnectTimeout but was wondering if there were other methods of handling this kind of problem.

    We also run several requests in parallel. Do you see any problems in doing this? Would you recommend we run the requests serially?

    Thanks,
    Sunny
     
    Last edited: May 23, 2017