How to send big data via SignalR in .NET client

折月煮酒 提交于 2019-12-01 14:58:41

问题


We have a .NET client, which use SignalR to call Server method, but the parameter seems very big, for such scenario how to fix it?

Client code:

public async Task FooAsync()
{
    var hubConnection = new HubConnection(...);
    await hubConnection.Start();

    var hubProxy = hubConnection.CreateHubProcx("ValueHub");
    //the content is very long, about 11776065 bytes (11MB)
    var content = File.ReadAllText(...);
    hubProxy.Invoke("Send", content);
    ...
}

Server code:

[HubName("ValueHub")]
public class ValueHub : Hub
{
    public void Send(string json)
    {

    }
}

From the exception stack and source code, I found the SignalR internally use HttpClient with the FormUrlEncodedContent type HttpContent, and maybe the limitation came from here.

System.UriFormatException was unhandled
  HResult=-2146233033
  Message=Invalid URI: The Uri string is too long.
  Source=System
  StackTrace:
       at System.UriHelper.EscapeString(String input, Int32 start, Int32 end, Char[] dest, Int32& destPos, Boolean isUriString, Char force1, Char force2, Char rsvd)
       at System.Uri.EscapeDataString(String stringToEscape)
       at System.Net.Http.FormUrlEncodedContent.Encode(String data)
       at System.Net.Http.FormUrlEncodedContent.GetContentByteArray(IEnumerable`1 nameValueCollection)
       at System.Net.Http.FormUrlEncodedContent..ctor(IEnumerable`1 nameValueCollection)
       at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.Post(String url, Action`1 prepareRequest, IDictionary`2 postData, Boolean isLongRunning)
       at Microsoft.AspNet.SignalR.Client.Transports.HttpBasedTransport.Send(IConnection connection, String data, String connectionData)
       at Microsoft.AspNet.SignalR.Client.Transports.AutoTransport.Send(IConnection connection, String data, String connectionData)
       at Microsoft.AspNet.SignalR.Client.Connection.Send(String data)
       at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[T](String method, Object[] args)
       at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke(String method, Object[] args)

Any good suggestions over this problem?


回答1:


As you have already gathered - this data is too much for SIGNALR by it's own design.

Would it not be a better idea to rather have another process that does this with a normal REST API (GET/POST). Perhaps a message indicating to the user that this needs to be done, as this feels very 'BATCH' like.

Secondly, if it a requirement (possible wrong tool for the job), have you considered compression.




回答2:


You can add a line that makes the message size 'infinite 'in your Startup.cs by setting the MaxIncomingWebSocketMessageSize to null:

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
        app.MapSignalR();
        GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;
        }
    }
} 

Mine works with ~200kb of data, 10 messages send consistently. I don't know how well it works if there is more data send per second though.




回答3:


its easy to do it..

  • split files into byte Array chunks (my tests shows max 10kb per chunk is enough)
  • send chunks to client with an invoke like (calculate totalBytes and the chunk data you have) :

    hubProxy.Invoke("Send", chunk,currentBytes,totalBytes);
    
  • get the chunks from client and create a byte array and append each chunk, signalr sends files syncronously, this means data will be received as your send order
  • you have totalbytes and currentBytes data, now you know all data received, save this byte array to a file with stream or whatever you like..



回答4:


add this to web config
<httpRuntime maxRequestLength="1048576" executionTimeout="600" />

then add this code to Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
        GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;
    }
}


来源:https://stackoverflow.com/questions/24262041/how-to-send-big-data-via-signalr-in-net-client

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!