首页 文章

如何从dotnet核心服务器向SignalR客户端发送二进制文件

提问于
浏览
0

我们有一个使用.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类 . 我添加了一种发送方法,将文件发送到特定客户端,而不是将其广播到每个客户端

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

1 回答

  • 1

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

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

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

相关问题