Как отправить большие данные через SignalR in.NET клиент
у нас есть клиент .NET, который использует SignalR для вызова метода сервера, но параметр кажется очень большим, для такого сценария как его исправить?
клиентский код:
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);
...
}
сервер код:
[HubName("ValueHub")]
public class ValueHub : Hub
{
public void Send(string json)
{
}
}
из стека исключений и исходного кода я нашел SignalR внутренне использовать HttpClient
С FormUrlEncodedContent
тип HttpContent
, и, возможно, ограничение пришло отсюда.
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)
хорошие предложения по этой проблеме?
3 ответов
Как вы уже собрали - эти данные слишком много для SIGNALR по его собственному дизайну.
не было бы лучше иметь другой процесс, который делает это с обычным REST API (GET/POST). Возможно, сообщение, указывающее пользователю, что это нужно сделать, так как это кажется очень "пакетным".
во-вторых, если это требование (возможно, неправильный инструмент для задания), вы рассматривали сжатие.
вы можете добавить строку, которая делает размер сообщения "бесконечным"в вашем запуске.cs, установив MaxIncomingWebSocketMessageSize в значение null:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;
}
}
}
шахта работает с ~200kb данных, 10 сообщений отправляют последовательно. Я не знаю, насколько хорошо это работает, если есть больше данных в секунду.
его легко сделать это..
- разделить файлы на куски массива байтов (мои тесты показывают, что Макс 10kb на кусок достаточно)
-
отправить куски клиенту с помощью вызова like (calculate
totalBytes
и данные куска, которые у вас есть):hubProxy.Invoke("Send", chunk,currentBytes,totalBytes);
- получите куски от клиента и создайте массив байтов и добавьте каждый кусок, signalr отправляет файлы синхронно, это означает, что данные будут получены в качестве вашего заказа на отправку
- вы
totalbytes
иcurrentBytes
данные, теперь вы знаете все полученные данные, сохраните этот массив байтов в файл с потоком или что угодно..