Как отправить большие данные через 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 данные, теперь вы знаете все полученные данные, сохраните этот массив байтов в файл с потоком или что угодно..