【问题标题】:how to send a binary file to SignalR client from server in dotnet core如何从 dotnet 核心中的服务器向 SignalR 客户端发送二进制文件
【发布时间】:2017-10-12 14:10:52
【问题描述】:

我们有一个使用 .Net 向 SignalR 客户端发送文件的解决方案 我们现在已经迁移到 .Net Core 在之前的 .net 解决方案中,我们习惯于通过 GlobalHost.ConnectionManager 来 Hub 上下文

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

在客户端,函数doStuffWithFile 将由两个参数触发。

new .Net Core 解决方案中,我通过从 Hub 派生创建了一个 Hub 类。我添加了一种 Send 方法将文件发送到特定客户端,而不是将其广播给每个人

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 方法,但它根本不起作用。你能告诉我怎么做吗?

【问题讨论】:

标签: c# signalr .net-core asp.net-core-signalr


【解决方案1】:

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

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

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

【讨论】:

  • 非常感谢,我的问题在于获取 HubContext,现在我可以通过示例中提到的 DI 来获取它。这真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多