如何将二进制文件从服务器dotnet的核心发送到SignalR客户

问题描述:

我们已经使用的.Net 发送文件到SignalR客户端的解决方案,我们现在已经搬到对.NET核心 在以前的.NET解决方案,我们通过GlobalHost.ConnectionManager如何将二进制文件从服务器dotnet的核心发送到SignalR客户

var myHub = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); 
myHub.Clients.Client(connectionId).doStuffWithFile(fileByteArray, fileName); 

,其中在客户端,功能使用集线器的上下文doStuffWithFile将与两个参数来触发。

新的.net核心解决方案我创建了一个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的新实例调用发送方法,只是它不工作。你能告诉我如何做到这一点?

+0

可能的重复https://stackoverflow.com/questions/46332651/signalr-call-client-methods-from-outside-the-hub-class-aspnetcore – Pawel

这不是对您的问题的直接回答,但希望它能帮助您找到解决方案。

将连接Id存储在静态类变量中是不正确的。每次新客户端连接时它都会更改,您无法控制要发送给哪个客户端。根据您提供的代码,您不清楚如何知道将文件发送给哪个客户端。请注意,当客户端断开连接时,您也可以设置_connectionId,因此很可能您会尝试将数据发送到您知道已关闭的连接。我实际上认为你会想要将目标连接ID或用户传递给集线器Send方法。我认为你可能没有足够的中心方法本身来解决连接ID,但由于连接ID是一个SignalR概念,它可能很难在SignalR组件之外访问它。这就是为什么使用用户而不是连接ID可能更容易(即Clients.User(...)而不是Clients.Client(...))。

GlobalHost不再存在于新的SignalR中。相反,您可以将IHubContext<THub>注入要调用该方法的类并使用InvokeAsyncHere是从Mvc控制器调用集线器方法的示例。

+0

非常感谢,我的问题是获得HubContext现在我可以通过示例中提到的DI来获得。这真的很有帮助。 –