Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Best HTTP Released

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

  1. wicea

    wicea

    Joined:
    Jan 23, 2016
    Posts:
    14
    @BestHTTP ah, thanks! Didn't see that you published new version, still used private package from you. I will update and check it.
     
  2. unity1_unity125

    unity1_unity125

    Joined:
    Nov 13, 2018
    Posts:
    2
    So according to you what is the best ping interval time for this issue. So I can set it in my code.

     
  3. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @unity1_unity125

    That depends on your needs and only you know how much uncertainty your app can tolerate. If you want fast feedback, you have to set it to a (very) low value and live with the additional overhead.
     
  4. SamuelGoldenbaum

    SamuelGoldenbaum

    Joined:
    May 21, 2017
    Posts:
    47
    @BestHTTP this really feels like a hack and I don't like the MessagePackTimestamp bleeding into the Unity project layers unnecessarily. Basic encoding/decoding of primitive types like dates, enums etc really should be supported out the box for a commercial product. I have spent 3 days now struggling to get generic lists, enums and now dates encoding/decoding using the recommended MessagePack protocol for Signal R Core. The examples are too basic and tests need to be in place for real-world usage. It is also incredibly frustrating using a forum thread for issue tracking and customers cannot be expected to trawl through +63 pages of posts as the forum search is really not great. Github's issue tracking would be a better solution and something developers are more accustomed to. Not trying to have a go here, just trying to offer some constructive feedback to help improve a great product.
     
  5. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @SamuelGoldenbaum

    I'm happy for all kind of feedback, I can learn from bad ones too. :)
    I'm available on a few places, including github (as you already know) and never refused to join a new one if got invited. As the MessagePack encoder is in the Examples folder and it have its own github repo, we can continue there if you want. I'm going to advertise it more as an issue tracker.

    As of the messagepack encoder: i hope you understand that i'm not the developer of the MessagePack serializer. For any incompatibilties with other encoders and/or encoding/decoding issues you should contact them. Any issues you found in my MessagePackProtocol class got fixed immediately and I offered to send it as well, but I can't take responsibility for the 3rd party implementation.
     
  6. SamuelGoldenbaum

    SamuelGoldenbaum

    Joined:
    May 21, 2017
    Posts:
    47
    This is a commercial product and you have made decisions about the libraries to partner with and have made explicit recommendations to use them. It is not fair to turn around and say that your customers should contact the developers of deprecated libraries when basic features do not work as expected.

    I am now on day 4 and facing further issues when receiving classes from the server. If a class includes a generic list and a dictionary as properties it throws if both are instantiated. If a date is included - as a MessagePackTimestamp as recommended, with either a List Or Dict, it fails. All is fine if only a single property is instantiated, but fails if more than once is used.

    Exception:
    Code (CSharp):
    1. [637179151287394190] Ex [HubConnection]: SendMessage - Message: 1: Cannot expand this MemoryStream   at BestHTTP.Extensions.BufferPoolMemoryStream.set_Capacity (System.Int32 value) [0x00027] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:175
    2.   at BestHTTP.Extensions.BufferPoolMemoryStream.Expand (System.Int32 newSize) [0x0000e] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:350
    3.   at BestHTTP.Extensions.BufferPoolMemoryStream.Write (System.Byte[] buffer, System.Int32 offset, System.Int32 count) [0x0007a] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:434
    4.   at GameDevWare.Serialization.MessagePack.MsgPackWriter.Write (System.String value) [0x0016a] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs:100
    5.   at GameDevWare.Serialization.JsonWriterExtentions.WriteString (GameDevWare.Serialization.IJsonWriter writer, System.String literal) [0x00025] in /Users/privateBestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:262
    6.   at GameDevWare.Serialization.MessagePack.MsgPackWriter.Write (GameDevWare.Serialization.JsonMember value) [0x00019] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs:110
    7.   at GameDevWare.Serialization.JsonWriterExtentions.WriteMember (GameDevWare.Serialization.IJsonWriter writer, System.String memberName) [0x00027] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:28
    8.   at GameDevWare.Serialization.Serializers.ObjectSerializer.Serialize (GameDevWare.Serialization.IJsonWriter writer, System.Object value) [0x000a0] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:111
    9.   at GameDevWare.Serialization.JsonWriterExtentions.WriteValue (GameDevWare.Serialization.IJsonWriter writer, System.Object value, System.Type valueType) [0x0003a] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:281
    10.   at BestHTTP.SignalRCore.Encoders.MessagePackProtocol.WriteValue (GameDevWare.Serialization.MessagePack.MsgPackWriter writer, System.Object value) [0x00012] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Examples/SignalRCore/Encoders/MessagePackProtocol.cs:235
    11.   at BestHTTP.SignalRCore.Encoders.MessagePackProtocol.EncodeMessage (BestHTTP.SignalRCore.Messages.Message message) [0x001fe] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Examples/SignalRCore/Encoders/MessagePackProtocol.cs:154
    12.   at BestHTTP.SignalRCore.HubConnection.SendMessage (BestHTTP.SignalRCore.Messages.Message message) [0x0003b] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:611   StackTrace:   at BestHTTP.Extensions.BufferPoolMemoryStream.set_Capacity (System.Int32 value) [0x00027] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:175
    13.   at BestHTTP.Extensions.BufferPoolMemoryStream.Expand (System.Int32 newSize) [0x0000e] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:350
    14.   at BestHTTP.Extensions.BufferPoolMemoryStream.Write (System.Byte[] buffer, System.Int32 offset, System.Int32 count) [0x0007a] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:434
    15.   at GameDevWare.Serialization.MessagePack.MsgPackWriter.Write (System.String value) [0x0016a] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs:100
    16.   at GameDevWare.Serialization.JsonWriterExtentions.WriteString (GameDevWare.Serialization.IJsonWriter writer, System.String literal) [0x00025] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:262
    17.   at GameDevWare.Serialization.MessagePack.MsgPackWriter.Write (GameDevWare.Serialization.JsonMember value) [0x00019] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs:110
    18.   at GameDevWare.Serialization.JsonWriterExtentions.WriteMember (GameDevWare.Serialization.IJsonWriter writer, System.String memberName) [0x00027] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:28
    19.   at GameDevWare.Serialization.Serializers.ObjectSerializer.Serialize (GameDevWare.Serialization.IJsonWriter writer, System.Object value) [0x000a0] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:111
    20.   at GameDevWare.Serialization.JsonWriterExtentions.WriteValue (GameDevWare.Serialization.IJsonWriter writer, System.Object value, System.Type valueType) [0x0003a] in /Users/private/BestHTTP Demo/Assets/Plugins/GameDevWare.Serialization/JsonWriterExtentions.cs:281
    21.   at BestHTTP.SignalRCore.Encoders.MessagePackProtocol.WriteValue (GameDevWare.Serialization.MessagePack.MsgPackWriter writer, System.Object value) [0x00012] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Examples/SignalRCore/Encoders/MessagePackProtocol.cs:235
    22.   at BestHTTP.SignalRCore.Encoders.MessagePackProtocol.EncodeMessage (BestHTTP.SignalRCore.Messages.Message message) [0x001fe] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Examples/SignalRCore/Encoders/MessagePackProtocol.cs:154
    23.   at BestHTTP.SignalRCore.HubConnection.SendMessage (BestHTTP.SignalRCore.Messages.Message message) [0x0003b] in /Users/private/BestHTTP Demo/Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:611
    24. UnityEngine.Debug:LogError(Object)
    25. BestHTTP.Logger.DefaultLogger:Exception(String, String, Exception) (at Assets/Best HTTP/Source/Logger/DefaultLogger.cs:111)
    26. BestHTTP.SignalRCore.HubConnection:SendMessage(Message) (at Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:620)
    27. BestHTTP.SignalRCore.HubConnection:InvokeImp(String, Object[], Action`1, Type, Boolean) (at Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:596)
    28. BestHTTP.SignalRCore.HubConnection:Invoke(String, Object[]) (at Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:502)
    29. <Connect>d__4:MoveNext() (at Assets/ServerManager.cs:139)
    30. System.Threading.Tasks.TaskCompletionSource`1:TrySetResult(String)
    31. BestHTTP.SignalRCore.<>c__DisplayClass89_0`1:<InvokeAsync>b__0(Message) (at Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:528)
    32. BestHTTP.SignalRCore.HubConnection:OnMessages(List`1) (at Assets/Best HTTP/Source/SignalRCore/HubConnection.cs:902)
    33. BestHTTP.SignalRCore.Transports.WebSocketTransport:OnBinary(WebSocket, Byte[]) (at Assets/Best HTTP/Source/SignalRCore/Transports/WebsocketTransport.cs:133)
    34. BestHTTP.WebSocket.WebSocket:<OnInternalRequestUpgraded>b__43_1(WebSocketResponse, Byte[]) (at Assets/Best HTTP/Source/WebSocket/WebSocket.cs:429)
    35. BestHTTP.WebSocket.WebSocketResponse:BestHTTP.Core.IProtocol.HandleEvents() (at Assets/Best HTTP/Source/WebSocket/WebSocketResponse.cs:550)
    36. BestHTTP.Core.ProtocolEventHelper:ProcessQueue() (at Assets/Best HTTP/Source/Core/ProtocolEvents.cs:69)
    37. BestHTTP.HTTPManager:OnUpdate() (at Assets/Best HTTP/Source/HTTPManager.cs:371)
    38. BestHTTP.HTTPUpdateDelegator:Update() (at Assets/Best HTTP/Source/HTTPUpdateDelegator.cs:165)
    39.  
    40.  
    Demo API:
    https://github.com/samuelgoldenbaum/BestHTTPDemoAPI

    Code (CSharp):
    1. namespace BestHTTPDemoAPI {
    2.     [Serializable]
    3.     [MessagePackObject (true)]
    4.     public class Move {
    5.         public int RollNumber;
    6.         public int Roll;
    7.         public int From;
    8.         public int To;
    9.     }
    10.  
    11.     [Serializable]
    12.     public enum TurnType {
    13.         Manual,
    14.         Automatic
    15.     }
    16.  
    17.     [Serializable]
    18.     public enum ActionType {
    19.         Start,
    20.         Roll,
    21.         Move,
    22.         Double,
    23.         Resign,
    24.         Forfit,
    25.         End,
    26.         AcceptDouble
    27.     }
    28.  
    29.     [Serializable]
    30.     public enum PlayerNumber {
    31.         One,
    32.         Two
    33.     }
    34.  
    35.     [Serializable]
    36.     [MessagePackObject (keyAsPropertyName: true)]
    37.     public class TurnAction {
    38.         public int TurnNumber;
    39.         public PlayerNumber PlayerNumber;
    40.         public ActionType ActionType;
    41.         public Dictionary<string, object> Data;
    42.  
    43.         public List<Move> Moves;
    44.         // public DateTime Time;
    45.     }
    46.  
    47.     public class GameHub : Hub {
    48.         public override async Task OnConnectedAsync () {
    49.             await Clients.All.SendAsync ("Send", $"{Context.ConnectionId} joined");
    50.         }
    51.  
    52.         public async Task JoinGroup (string groupName) {
    53.             await Groups.AddToGroupAsync (Context.ConnectionId, groupName);
    54.  
    55.             await Clients.Group (groupName).SendAsync ("Send", $"{Context.ConnectionId} joined {groupName}");
    56.         }
    57.  
    58.         public async Task TurnAction (TurnAction turnAction) {
    59.             await Clients.Group ("game").SendAsync ("TurnAction", turnAction);
    60.         }
    61.     }
    62. }
    Client:
    I have invited you to review a demo client on GitHub.

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Text;
    4. using BestHTTP.SignalRCore;
    5. using BestHTTP.SignalRCore.Encoders;
    6. using GameDevWare.Serialization.MessagePack;
    7. using UnityEngine;
    8.  
    9. [Serializable]
    10. public class Move {
    11.     public int RollNumber;
    12.     public int Roll;
    13.     public int From;
    14.     public int To;
    15.  
    16.     public Move () { }
    17.  
    18.     public Move (int rollNumber, int roll, int from, int to) {
    19.         RollNumber = rollNumber;
    20.         Roll = roll;
    21.         From = from;
    22.         To = to;
    23.     }
    24. }
    25.  
    26. [Serializable]
    27. public enum TurnType {
    28.     Manual = 1,
    29.     Automatic = 2
    30. }
    31.  
    32. [Serializable]
    33. public enum PlayerNumber {
    34.     One,
    35.     Two
    36. }
    37.  
    38. public enum ActionType {
    39.     Start,
    40.     Roll,
    41.     Move,
    42.     Double,
    43.     Resign,
    44.     Forfit,
    45.     End,
    46.     AcceptDouble
    47. }
    48.  
    49. [Serializable]
    50. public class TurnAction {
    51.     public int TurnNumber;
    52.     public PlayerNumber PlayerNumber;
    53.     public ActionType ActionType;
    54.     public Dictionary<string, object> Data;
    55.     public List<Move> Moves;
    56.  
    57.     // public MessagePackTimestamp Time;
    58. }
    59.  
    60. public class ServerManager : MonoBehaviour {
    61.     HubConnection hub;
    62.  
    63.     void Start () {
    64.         Connect ();
    65.     }
    66.  
    67.     void OnDestroy () {
    68.         if (hub != null) {
    69.             hub.StartClose ();
    70.         }
    71.     }
    72.  
    73.     void ReceiveTurnAction (TurnAction turnAction) {
    74.         var sb = new StringBuilder ();
    75.         sb.Append ($"TurnNumber: {turnAction.TurnNumber}, Time: , PlayerNumber: {turnAction.PlayerNumber}, ActionType: {turnAction.ActionType}");
    76.  
    77.         if (turnAction.Data != null) {
    78.             sb.Append ($", Data roll1: {turnAction.Data["1"]} roll2: {turnAction.Data["2"]}");
    79.         }
    80.  
    81.         Debug.Log (sb.ToString ());
    82.     }
    83.  
    84.     async void Connect () {
    85.         hub = new HubConnection (new Uri ("https://localhost:5001/gameHub"), new MessagePackProtocol ());
    86.  
    87.         hub.OnError += Hub_OnError;
    88.  
    89.         hub.On ("Send", (string arg) => { Debug.Log ($"On '<color=green>Send</color>': '<color=yellow>{arg}</color>'"); });
    90.  
    91.         hub.On<TurnAction> ("TurnAction", ReceiveTurnAction);
    92.  
    93.         await hub.ConnectAsync ();
    94.  
    95.         await hub.InvokeAsync<string> ("JoinGroup", "game");
    96.  
    97.         Debug.Log ("Hub_OnConnected");
    98.  
    99.         var now = DateTime.UtcNow;
    100.         var epoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    101.  
    102.         // will succeed as only the Data property is instantiated
    103.         hub.Invoke<TurnAction> ("TurnAction", new TurnAction {
    104.             TurnNumber = 1,
    105.             PlayerNumber = PlayerNumber.One,
    106.             ActionType = ActionType.Roll,
    107.             Data = new Dictionary<string, object> {{"1", 6}, {"2", 6}},
    108.             // Moves = new List<Move> {
    109.             //     new Move {
    110.             //         From = 1,
    111.             //         Roll = 2,
    112.             //         RollNumber = 1,
    113.             //         To = 3
    114.             //     },
    115.             //     new Move {
    116.             //         From = 3,
    117.             //         Roll = 1,
    118.             //         RollNumber = 2,
    119.             //         To = 4
    120.             //     }
    121.             // },
    122.             // Time = new MessagePackTimestamp ((long) (now.ToUniversalTime () - epoch).TotalSeconds, 0),
    123.         });
    124.  
    125.         now = DateTime.UtcNow;
    126.         epoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    127.  
    128.         // will succeed as only the Moves property is instantiated and Data is left null
    129.         hub.Invoke<TurnAction> ("TurnAction", new TurnAction {
    130.             TurnNumber = 2,
    131.             PlayerNumber = PlayerNumber.Two,
    132.             ActionType = ActionType.Move,
    133.             // Data = new Dictionary<string, object> {{"1", 6}, {"2", 6}},
    134.             Moves = new List<Move> {
    135.                 new Move {
    136.                     From = 1,
    137.                     Roll = 2,
    138.                     RollNumber = 1,
    139.                     To = 3
    140.                 },
    141.                 new Move {
    142.                     From = 3,
    143.                     Roll = 1,
    144.                     RollNumber = 2,
    145.                     To = 4
    146.                 }
    147.             },
    148.             // Time = new MessagePackTimestamp ((long) (now.ToUniversalTime () - epoch).TotalSeconds, 0),
    149.         });
    150.  
    151.         // fails when both Moves and Data are instantiated
    152.         hub.Invoke<TurnAction> ("TurnAction", new TurnAction {
    153.             TurnNumber = 3,
    154.             PlayerNumber = PlayerNumber.One,
    155.             ActionType = ActionType.Roll,
    156.             Data = new Dictionary<string, object> {{"1", 6}, {"2", 6}},
    157.             Moves = new List<Move> {
    158.                 new Move {
    159.                     From = 1,
    160.                     Roll = 2,
    161.                     RollNumber = 1,
    162.                     To = 3
    163.                 },
    164.                 new Move {
    165.                     From = 3,
    166.                     Roll = 1,
    167.                     RollNumber = 2,
    168.                     To = 4
    169.                 }
    170.             },
    171.             // Time = new MessagePackTimestamp ((long) (now.ToUniversalTime () - epoch).TotalSeconds, 0),
    172.         });
    173.     }
    174.  
    175.     void Hub_OnError (HubConnection hubConnection, string error) {
    176.         Debug.LogError ($"Hub_OnError: error: {error}");
    177.     }
    178. }
     
    Last edited: Feb 22, 2020
  7. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @SamuelGoldenbaum

    Uploaded a fix for the exception to your repo. Also added DateTime encode/decode support.
     
    SamuelGoldenbaum likes this.
  8. SamuelGoldenbaum

    SamuelGoldenbaum

    Joined:
    May 21, 2017
    Posts:
    47
    @BestHTTP Thanks and much appreciated - have tested and can confirm all working as expected. :)
     
  9. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @SamuelGoldenbaum

    Great! All fixes and improvements will be included in the next release, so you can update the plugin as usually.
     
    SamuelGoldenbaum likes this.
  10. shawnepdmartin

    shawnepdmartin

    Joined:
    Jul 27, 2015
    Posts:
    85
    Ok sell me! Not entirely sure this is what I need or not but I'm starting to think about the boring account management aspect of my game. Will this asset make these things easier/possible?

    1. Login System.. Sends data to some sort of SQL DB, validates, logs in or creates new account...
    2. Leaderboards.. Sends basic stats to DB
    3. I spent WAY too much time building a sophisticated YouTube Playlist UI and video player... Would be rad to have that saved in a DB as well.

    This way I can also develop a website backend where players can also login and edit their Playlist from a more convenient interface..

    I'm currently not doing any multiplayer, although I may develop a ghost runner aspect where you can race against others ghosts "offline" (race against the fastest time trial basically)

    After typing this I realize most of what I'm looking for is a convenient DB interface. I feel this may be overkill?
     
    Cromfeli likes this.
  11. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @shawnepdmartin

    Yep, seems that you need a different kind of plugin/solution. My plugin could help in the client<=>server communication (upload and download) only.
     
    Cromfeli likes this.
  12. shawnepdmartin

    shawnepdmartin

    Joined:
    Jul 27, 2015
    Posts:
    85
    Appreciate the response! Thanks
     
  13. duartedd

    duartedd

    Joined:
    Aug 1, 2017
    Posts:
    65
    Hello how easy will.it be to setup auth2 on this for eg with windows or android single sign into Google or other OpenID 2.0 compliant providers?
     
  14. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @duartedd

    It's not an oauth client, but it has everything that needed to implement one.
     
  15. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,025
    Hi @BestHTTP

    I'm using your amazing library to download files, and now its suddenly just stopped working without throwing any error or any clue.

    What happens is that, while file is being downloaded with this simple snippet, after some download progress, its just stops, neither progress event, nor error or response event.

    For example in following case its just stopped at 63%

    Please advise


    Capture.PNG
     
  16. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    jGate99 likes this.
  17. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,025
    Hi it looks like error was due to not using streaming.
    Now im using Streaming however im not getting progress callback like (1%, 2%, 100% done) anymore, please advise
    https://besthttp-documentation.read...P Request/Advanced Topics/Download Streaming/
     
  18. OdedEisenPixi

    OdedEisenPixi

    Joined:
    Aug 27, 2019
    Posts:
    7
    Hello @BestHTTP ,
    I started to test the usage of SignalR Core, and mostly it works great.
    One issue though - when there's a an open connection to a hub, and I stop playing on unity (without call to Close of the hubConnection):

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. BestHTTP.WebSocket.WebSocketResponse.ReceiveThreadFunc () (at Assets/Best HTTP/Source/WebSocket/WebSocketResponse.cs:485)
    3. BestHTTP.PlatformSupport.Threading.ThreadedRunner+<>c__DisplayClass4_0.<RunLongLiving>b__0 (System.Object param) (at Assets/Best HTTP/Source/PlatformSupport/Threading/ThreadedRunner.cs:83)
    4. ystem.Threading.ThreadHelper.ThreadStart_Context (System.Object state) (at <567df3e0919241ba98db88bec4c6696f>:0)
    5. System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) (at <567df3e0919241ba98db88bec4c6696f>:0)
    6. System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) (at <567df3e0919241ba98db88bec4c6696f>:0)
    7. System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) (at <567df3e0919241ba98db88bec4c6696f>:0)
    8. System.Threading.ThreadHelper.ThreadStart (System.Object obj) (at <567df3e0919241ba98db88bec4c6696f>:0)
    9. UnityEngine.UnhandledExceptionHandler:<RegisterUECatcher>m__0(Object, UnhandledExceptionEventArgs) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnhandledExceptionHandler.bindings.cs:46)
    this happens even in the BestHttp example scene, with "Test Hub". ("Test Hub With Async-Await" doesn't seems to work at all in the scene)
    Adding hub?.StartClose() or await hub?.CloseAsync() in the OnDestroy doesn't help either, and still getting the exception.
     
  19. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @jGate99

    Just tried out my streaming sample and it's still working. Could you send your log file to me (link for instructions is in my last comment)?
     
  20. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @OdedEisenPixi

    This should be fixed in the next version. Sent a link in private to a new package.
     
  21. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,025
    Sorry for misunderstanding, your stream sample for file is working. but now following callback doesnt show progress as expected
    request.OnDownloadProgress = OnDownloadProgress;

    void OnDownloadProgress(HTTPRequest request, long downloaded, long length) {
    float progressPercent = (downloaded / (float)length) * 100.0f;
    Debug.Log("Downloaded: " + progressPercent.ToString("F2") + "%");
    }
     
  22. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
  23. OdedEisenPixi

    OdedEisenPixi

    Joined:
    Aug 27, 2019
    Posts:
    7
  24. umityayla

    umityayla

    Joined:
    May 21, 2019
    Posts:
    15
    Hello @BestHTTP ,

    We are currently using this socket.io library. But we started to see some of our callbacks going missing, because of that entire callback system turns into garbage, does besthttp have a solution for this? Or is there a way to prevent callbacks going missing?
     
    Last edited: Mar 13, 2020
  25. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @umityayla

    I don't know about any such issues with my plugin.
     
    Last edited: Mar 13, 2020
  26. kavinvardhanNW

    kavinvardhanNW

    Joined:
    Jul 30, 2018
    Posts:
    2
    @BestHTTP I'm having a problem with timeouts during a HTTP request. I'm sending a request to a test url which gives a response after a few seconds which I've specified. So, I test with a 10 second delayed response, and added

    request.Timeout = TimeSpan.FromSeconds(5);
    request.Send();

    before sending the request, as per the documentation. But, I'm not getting a TimedOut state callback after 5 seconds, rather I'm getting the callback after 10 seconds (when the actual response was supposed to be received). I've tested with request.ConnectTimeout too, but I get the same response. How can I solve this problem?
     
    Last edited: Mar 18, 2020
  27. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
  28. umityayla

    umityayla

    Joined:
    May 21, 2019
    Posts:
    15
    Hello @BestHTTP sorry for bothering you once more,

    We are still on the testing phase of your plugin. But we have a problem. But I need to tell you step by step;
    1-We connect to the game and we don't encounter any problems for a while.
    2-Then we lock the phone which probably freezes the game thread.
    3-When we come back socket connects back again then things run smooth a while
    4-But after a few emits, we stop receiving callbacks.

    Thank you for your replies.
     
  29. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
  30. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @kavinvardhanNW

    Sent a link to an updated package in a private message.
     
  31. kavinvardhanNW

    kavinvardhanNW

    Joined:
    Jul 30, 2018
    Posts:
    2
    @BestHTTP will test it out and let you know!
     
  32. SamuelGoldenbaum

    SamuelGoldenbaum

    Joined:
    May 21, 2017
    Posts:
    47
    Not so much a bug, but trying to work out the correct way to have the SignalR Core client keep trying to connect if the initial connection fails - not related to RetryPolicy.
    1. I cannot find a timeout property anywhere for SignalR Core connection. See. 1. below
    2. Attempting to simply fire off ConnectAsync again will continue to fail as the State is not reset when connecting and there is no way to reset it other than instantiating new creating a new connection instance. See 2. below
    3. Wrapping a try around and loop around ConnectAsync() doesn't work on IL2CPP builds. It stops after first connect error - only on IL2CPP (iOS) See 3. below
    1. New connection does not accept a timeout:
    HubConnection.cs line 279:
    Code (CSharp):
    1. var request = new HTTPRequest(builder.Uri, HTTPMethods.Post, OnNegotiationRequestFinished);
    2.             if (this.AuthenticationProvider != null)
    3.                 this.AuthenticationProvider.PrepareRequest(request);
    4.          
    5.             request.Send();
    2. New connection does not reset state:
    HubConnection.cs line 181:
    Code (CSharp):
    1.  
    2. public Task<HubConnection> ConnectAsync()
    3. {
    4.     if (this.State != ConnectionStates.Initial && this.State != ConnectionStates.Redirected && this.State != ConnectionStates.Reconnecting)
    5.         throw new Exception("HubConnection - ConnectAsync - Expected Initial or Redirected state, got " + this.State.ToString());
    6.  
    3. Reconnect loop fails on ILC2PP build - errors once and exits loop:

    Code (CSharp):
    1.  
    2. await ConnectAsync();
    3. ...
    4.  
    5. public async Task ConnectAsync () {
    6.         // Keep trying to until we can start or the token is canceled.
    7.         while (!cancellationTokenSource.IsCancellationRequested) {
    8.             try {
    9.                 // have to instantiate a new connection here
    10.                 connection = new HubConnection (new Uri (apiURL), new MessagePackProtocol ()) {
    11.                     ReconnectPolicy = new RandomRetryPolicy (),
    12.                 };
    13.  
    14.                 await connection.ConnectAsync ();
    15.  
    16.                 connection.OnError += (hubConnection, error) => { Debug.LogWarning ($"ServerManager: {error}"); };
    17.                 // all ok, bind to events etc
    18.                 ...
    19.  
    20.                 return;
    21.             }
    22.             catch when (cancellationTokenSource.IsCancellationRequested) {
    23.                 return;
    24.             }
    25.             catch (Exception ex) {
    26.                 // Failed to connect, trying again in 1000 ms.
    27.                 await Task.Delay (1000);
    28.             }
    29.         }
    30.     }
    XCode Console:
    Code (CSharp):
    1. ApplicationException: Cannot connect
    2.    at AsyncTest..cctor () [0x00000] in <00000000000000000000000000000000>:0
    3.    at System.Linq.Expressions.StackGuard.RunOnEmptyStack[T1,T2] (System.Action`2[T1,T2] action, T1 arg1, T2 arg2) [0x00000] in <00000000000000000000000000000000>:0
    4.    at AsyncTest.ConnectAsync () [0x00000] in <00000000000000000000000000000000>:0
    5.    at AsyncTest..cctor () [0x00000] in <00000000000000000000000000000000>:0
    6.    at System.Linq.Expressions.StackGuard.RunOnEmptyStack[T1,T2] (System.Action`2[T1,T2] action, T1 arg1, T2 arg2) [0x00000] in <00000000000000000000000000000000>:0
    7.    at AsyncTest.Connect () [0x00000] in <00000000000000000000000000000000>:0
    8.    at UnityEngine.Events.UnityAction.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    9.    at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    10.    at UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1].Invoke (T1 handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    11.    at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
    12.    at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchPress (UnityEngine.EventSystems.PointerEventData pointerEvent, System.Boolean pressed, System.Boolean released) [0x00000] in <00000000000000000000000000000000>:0
    13.    at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchEvents () [0x00000] in <00000000000000000000000000000000>:0
    14.    at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
    15. --- End of stack trace from previous location where exception was thrown ---
    16.    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0
    17.    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00000] in <00000000000000000000000000000000>:0
    18.    at AsyncTest..cctor () [0x00000] in <00000000000000000000000000000000>:0
    19.    at System.Linq.Expressions.StackGuard.RunOnEmptyStack[T1,T2] (System.Action`2[T1,T2] action, T1 arg1, T2 arg2) [0x00000] in <00000000000000000000000000000000>:0
    20.    at AsyncTest.Connect () [0x00000] in <00000000000000000000000000000000>:0
    21.    at UnityEngine.Events.UnityAction.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    22.    at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    23.    at UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1].Invoke (T1 handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    24.    at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
    25.    at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchPress (UnityEngine.EventSystems.PointerEventData pointerEvent, System.Boolean pressed, System.Boolean released) [0x00000] in <00000000000000000000000000000000>:0
    26.    at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchEvents () [0x00000] in <00000000000000000000000000000000>:0
    27.    at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
    28. --- End of stack trace from previous location where exception was thrown ---
    29.    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0
    30.    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
    31.    at System.Threading.SendOrPostCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
    32.    at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
    33.    at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
    34. UnityEngine.UnitySynchronizationContext:Exec()
    35. UnityEngine.UnitySynchronizationContext:Exec()

     
  33. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @SamuelGoldenbaum

    1.) There's no such timeout for the HubConnection and while every HTTPRequest has its own, the HubConnection might send out multiple requests and some of them are not controlled by the HubConnection (requests sent by the AuthenticationProvider).
    For HTTPRequest you can set a global default one:
    Code (CSharp):
    1. HTTPManager.RequestTimeout = TimeSpan.FromSeconds(120);
    Or you can extend the authenticator and set timeouts for the requests in its PrepareRequest call.
    Wrote a feature request in my public tracker that you can subscribe to.

    2.) Yep, that's intentional. Calling connect again when there's a failure can mean two things: try to resume (retry the last operation) or start over completly. Both can be valid and logical and both have its pros and cons.
    You can write a feature request.

    3.) Tried to replicate it without any luck. It seems to be an il2cpp code generation issue if it doesn't match behavior. I would recommend to report the bug to Unity.
     
    SamuelGoldenbaum likes this.
  34. SamuelGoldenbaum

    SamuelGoldenbaum

    Joined:
    May 21, 2017
    Posts:
    47
    I can confirm that the below does not adjust the timeout
    Code (CSharp):
    1.  
    2. HTTPManager.RequestTimeout = TimeSpan.FromSeconds(120);
    3. connection = new HubConnection (new Uri (apiURL), new MessagePackProtocol ()) {
    4.     ReconnectPolicy = new RandomRetryPolicy (),
    5. };
    6.  
    PS, where can we find the feature requests?
     
    Last edited: Mar 26, 2020
  35. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
  36. vuluu

    vuluu

    Joined:
    Jun 19, 2019
    Posts:
    11
    Hi @BestHTTP
    After updated to latest version 2.0.5. Sometime I see an error "Curl error 52: Empty reply from server". Is it from this plugin or Unity and what does it mean? I tried enable debug log but see nothing else. Below is the editor log. I never see it before

     
  37. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @vuluu

    That's an error from Unity itself. The plugin doesn't use cURL or Unity's webrequests.
     
  38. vuluu

    vuluu

    Joined:
    Jun 19, 2019
    Posts:
    11
    Thank you for your help. After searching more, I see that is a known Unity bug happened recently.
     
  39. akitsu

    akitsu

    Joined:
    Nov 26, 2013
    Posts:
    38
    Hello we were updating the plugin from 1.x to newest. Biggest problem we are having the function GetStreamedFragments() is missing. We would save list of byte array to file like

    Code (CSharp):
    1. private void SaveFragments(List<byte[]> fragments)
    2.     {
    3.         if (fragments == null)
    4.         {
    5.             return;
    6.         }
    7.  
    8.         using (FileStream fs = new FileStream(filename, FileMode.Append))
    9.         {
    10.             for (int i = 0; i < fragments.Count; ++i)
    11.             {
    12.                 if (fragments[i] == null)
    13.                 {
    14.                     Debug.LogError("BundleDownload: Null inside list of fragments");
    15.                     continue;
    16.                 }
    17.                 bytesDownloaded = bytesDownloaded + (uint)fragments[i].Length;
    18.                 fs.Write(fragments[i], 0, fragments[i].Length);
    19.             }
    20.         }
    21.     }
    So we would translate this to new OnStreamingData which gives you byte array.
     
  40. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @akitsu

    You can find a 'Streaming into a file' example in the documentation: https://besthttp-documentation.read...ics/Download Streaming/#streaming-into-a-file

    Code (CSharp):
    1. var request = new HTTPRequest(new Uri(url), OnRequestFinished);
    2.  
    3. request.OnStreamingData += OnData;
    4.  
    5. request.Send();
    6.  
    7. private bool OnData(HTTPRequest req, HTTPResponse resp, byte[] dataFragment, int dataFragmentLength)
    8. {
    9.     if (resp.IsSuccess)
    10.     {
    11.         var fs = req.Tag as System.IO.FileStream;
    12.         if (fs == null)
    13.             req.Tag = fs = new System.IO.FileStream("fileName", System.IO.FileMode.Create);
    14.  
    15.         fs.Write(dataFragment, 0, dataFragmentLength);
    16.     }
    17.  
    18.     // Return true if dataFrament is processed so the plugin can recycle the byte[]
    19.     return true;
    20. }
    21.  
    22. private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
    23. {
    24.     var fs = req.Tag as System.IO.FileStream;
    25.     if (fs != null)
    26.         fs.Dispose();
    27.  
    28.     switch (req.State)
    29.     {
    30.         // The request finished without any problem.
    31.         case HTTPRequestStates.Finished:
    32.             if (resp.IsSuccess)
    33.             {
    34.                 Debug.Log("Done!");
    35.             }
    36.             else
    37.             {
    38.                 Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    39.                                                 resp.StatusCode,
    40.                                                 resp.Message,
    41.                                                 resp.DataAsText));
    42.             }
    43.             break;
    44.  
    45.         default:
    46.                 // There were an error while downloading the content.
    47.                 // The incomplete file should be deleted.
    48.                 System.IO.File.Delete("filename");
    49.             break;
    50.     }
    51. }
     
  41. Volpi91

    Volpi91

    Joined:
    Nov 5, 2017
    Posts:
    3
    So got it working. I did read that BestHTTP has decompressing feature. Do you have any example for this feature?
     
  42. Shankar-Ganesh

    Shankar-Ganesh

    Joined:
    Sep 23, 2013
    Posts:
    6
    Hi @BestHTTP

    If we see the requests posted in Charles log interface we can able to see the Host column like 192.168.1.40:80 and in Path column http://192.168.1.40/example/users/regtoken

    It should be like in Host 192.168.1.40 and in Path should be /example/users/regtoken

    What should do we for that?
     
  43. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @Volpi91

    Decompression is done automatically when the server sends gzip compressed content.

    An example could be this request:
    Code (CSharp):
    1. var request = new HTTPRequest(new Uri("https://httpbin.org/gzip"), OnRequestFinished);
    2. request.Send();
    3.  
    4. private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
    5. {
    6.     switch (req.State)
    7.     {
    8.         // The request finished without any problem.
    9.         case HTTPRequestStates.Finished:
    10.             if (resp.IsSuccess)
    11.             {
    12.                 Debug.Log(resp.DataAsText);
    13.             }
    14.             else
    15.             {
    16.                 Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    17.                                                 resp.StatusCode,
    18.                                                 resp.Message,
    19.                                                 resp.DataAsText));
    20.             }
    21.             break;
    22.  
    23.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    24.         case HTTPRequestStates.Error:
    25.             Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    26.             break;
    27.  
    28.         // The request aborted, initiated by the user.
    29.         case HTTPRequestStates.Aborted:
    30.             Debug.LogWarning("Request Aborted!");
    31.             break;
    32.  
    33.         // Connecting to the server is timed out.
    34.         case HTTPRequestStates.ConnectionTimedOut:
    35.             Debug.LogError("Connection Timed Out!");
    36.             break;
    37.  
    38.         // The request didn't finished in the given time.
    39.         case HTTPRequestStates.TimedOut:
    40.             Debug.LogError("Processing the request Timed Out!");
    41.             break;
    42.     }
    43. }
    The server sends back the response gzip compressed, but instead of seeing binary data, it should print out a json text.
     
  44. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @Shankar-Ganesh

    Sending the port number too is valid, although the plugin shouldn't send it for the default ports (80 and 443).
     
  45. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
  46. Shankar-Ganesh

    Shankar-Ganesh

    Joined:
    Sep 23, 2013
    Posts:
    6
    Last edited: Mar 30, 2020
  47. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @Shankar-Ganesh

    Depending on how you set up the HTTPProxy it can include the whole uri. The HTTPProxy's constructor has a sendWholeUri param that you can set to false.
    You can also send me a full log that i could inspect.
     
  48. Shankar-Ganesh

    Shankar-Ganesh

    Joined:
    Sep 23, 2013
    Posts:
    6
    Sure. Before that I can try what you have suggested to set the sendWholeUri to false. Previously we have used the below code.

    HTTPManager.Proxy = new HTTPProxy(new System.Uri(URL));

    And now it should be like(if I am not wrong)
    HTTPManager.Proxy = new HTTPProxy(new System.Uri(URL), null, false, false, false);
     
  49. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,492
    @Shankar-Ganesh

    With Charles, using it like this might be better (this is how i'm using it):
    Code (CSharp):
    1. HTTPManager.Proxy = new HTTPProxy(new System.Uri(URL), null, true);
    The default (failsafe) setup is to treat the proxy as a non-transparent one, but as i can remember Charles enables transparent proxying by default (or as an alternate, you can turn it on) so the isTransparent param can be true.
     
  50. Shankar-Ganesh

    Shankar-Ganesh

    Joined:
    Sep 23, 2013
    Posts:
    6
    Having few more doubts,

    1. To enable proxy, is network_security_config.xml file is mandatory from Android 7 and above OS to be tested in the Mobile? Also shall we delete the network_security_config.xml while moving it to production?

    2. Do we really required the sub domain url in the network_security_config.xml?

    3. Will Socket I/O has a separate proxy or it will work with the same HTTPProxy?
     
unityunity