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

本文关键字:SignalR 数据 net 客户端 | 更新日期: 2023-09-27 18:08:52

我们有一个。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内部使用HttpClientFormUrlEncodedContent类型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)
对于这个问题有什么好的建议吗?

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

你可以通过设置maxxincomingwebsocketmessagesize为空,在Startup.cs中添加一行使消息大小为'infinite ':

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

我的工作与~200kb的数据,10条消息发送一致。我不知道如果每秒有更多的数据发送,它的工作效果如何。

正如您已经收集到的那样- SIGNALR自己设计的这些数据太多了。

如果有另一个进程使用普通的REST API (GET/POST)来完成这个任务,这不是更好的主意吗?可能会有一条消息告诉用户需要完成这个操作,因为这感觉很像"BATCH"。

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

这很容易。

  • 将文件分割成字节数组块(我的测试显示每个块最大10kb就足够了)
  • 发送块到客户端调用(计算totalBytes和块数据你有):

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

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

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

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