如何在.NET客户端通过SignalR发送大数据

时间:2014-06-17 10:58:09

标签: c# asp.net signalr signalr.client

我们有一个.NET客户端,它使用SignalR来调用Server方法,但参数看起来非常大,对于这种情况如何修复它?

客户代码:

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)

对这个问题有什么好的建议吗?

5 个答案:

答案 0 :(得分:13)

您可以通过将MaxIncomingWebSocketMessageSize设置为null来在Startup.cs中添加一条使消息大小为“无限”的行:

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

Mine使用大约200kb的数据,10条消息一致发送。 如果每秒发送更多数据,我不知道它有多好。

答案 1 :(得分:6)

正如您已经收集到的那样 - 这个数据对于SIGNALR来说太过分了。

使用普通的REST API(GET / POST)来做另一个进程是不是更好。也许是向用户表明需要这样做的消息,因为这感觉非常“批量”。等。

其次,如果它是一个要求(可能是工作的错误工具),你是否考虑过压缩。

答案 2 :(得分:2)

很容易做到..

  • 将文件拆分为字节数组块(我的测试显示每个块最多10kb就足够了)
  • 使用类似(计算totalBytes和您拥有的块数据)的调用将块发送到客户端:

    hubProxy.Invoke("Send", chunk,currentBytes,totalBytes);
    
  • 从客户端获取块并创建一个字节数组并追加每个块,signalr同步发送文件,这意味着数据将作为您的发送订单接收
  • 您有totalbytescurrentBytes数据,现在您知道收到的所有数据,将此字节数组保存到包含流或您喜欢的任何内容的文件中。

答案 3 :(得分:2)

对于ConfigureServices(IServiceCollection services)方法中startup.cs中的点网核心,添加以下行

services.AddSignalR(conf =>
{
      conf.MaximumReceiveMessageSize = null;
}

答案 4 :(得分:0)

将此添加到Web配置
<httpRuntime maxRequestLength="1048576" executionTimeout="600" />

然后将此代码添加到Startup.cs

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