问题
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
totalBytesand 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
totalbytesandcurrentBytesdata, 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