我们有一个使用.Net向SignalR客户端发送文件的解决方案
我们现在已转移到 .Net Core
在之前的.net解决方案中,我们通过GlobalHost.ConnectionManager
var myHub = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
myHub.Clients.Client(connectionId).doStuffWithFile(fileByteArray, fileName);
在客户端,使用两个参数触发函数doStuffWithFile
。
在新的.Net Core 解决方案中,我通过从Hub派生来创建了一个Hub类。我添加了一种发送方法,将文件发送到特定客户端,而不是将其广播到每个客户端
public class MyHub : Hub
{
private static string _connectionId;
public override Task OnConnectedAsync()
{
_connectionId = Context.ConnectionId;
return Task.CompletedTask;
}
public override Task OnDisconnectedAsync(Exception exception)
{
_connectionId = Context.ConnectionId;
//// remove Connection Id
return base.OnDisconnectedAsync(exception);
}
public async Task Send(byte[] fileByteArray, string fileName)
{
await Clients.Client(_connectionId).InvokeAsync("doStuff", fileByteArray, fileName);
}
}
但是,我没有.Net核心中的任何机制,如GlobalHost或ConnectionManager来获取HubContext来发送文件。
在客户端:
static void Main(string[] args)
{
var connection = new HubConnectionBuilder()
.WithUrl("http://localhost:25786/file")
.WithConsoleLogger()
.Build();
connection.On<byte[], string>("doStuff", DoStuff);
connection.StartAsync().ContinueWith(
task =>
{
if (task.IsFaulted)
{
Console.WriteLine("Connection faulty");
}
});
Console.ReadLine();
}
private static void DoStuff(byte[] data, string name)
{
File.WriteAllBytes(@"c:\Projects\" + name, data);
}
我尝试创建一个新的MyHub实例来调用Send方法,但它只是不起作用。你能告诉我怎么做吗?
答案 0 :(得分:1)
这不是您问题的直接答案,但希望它能帮助您找到解决方案。
在静态类变量中存储连接ID不正确。它会在每次新客户端连接时更改,并且您无法控制要发送到哪个客户端。从您提供的代码中,您不清楚如何知道将文件发送到哪个客户端。请注意,您还在客户端断开连接时设置_connectionId
,因此您可能会尝试将数据发送到已知关闭的连接。我实际上认为您希望将目标连接ID或用户传递给hub Send
方法。我认为hub方法本身可能没有足够的上下文来解析连接ID,但由于连接id是SignalR概念,因此很难在SignalR组件外部访问它。这就是为什么使用用户而不是连接ID(即Clients.User(...)
而不是Clients.Client(...
)可能更容易。
GlobalHost
。相反,您可以将IHubContext<THub>
注入要调用方法的类,并使用InvokeAsync
。 Here是从Mvc控制器调用集线器方法的示例。