【问题标题】:Signalr with WinForms and Framework 4.8 MVC带有 WinForms 和 Framework 4.8 MVC 的 Signalr
【发布时间】:2021-11-06 04:44:03
【问题描述】:

我正在尝试使用信号器作为通知程序来创建工作通知流程。我的情况是我有一个 winforms 项目,它将控制过程的各个阶段。进程在 MVC 项目中影响的系统。

就目前而言,我有以下项目: 进程(Winforms) 系统(框架 4.8 MVC) 服务(框架 4.8) SignalRSelfHost(控制台)

服务层被流程和系统项目引用,并包含流程每个步骤的逻辑。当一个阶段开始或结束时,它需要调用连接的客户端并让他们知道..

我最初在 System 项目中创建了信号器的东西,并且能够从页面上的按钮调用服务方法,并按预期传递开始/结束消息。然后我创建了 winforms 应用程序并调用了相同的服务方法。当我这样做时,没有消息发送到网络客户端。

值得一提的是,winforms项目对signalr一无所知,它留给服务使用这个与signalr进行协商:

            var context = GlobalHost.ConnectionManager.GetHubContext<ProcessHub>();
            context.Clients.All.StageStarted(stage.started);

然后让我感到震惊的是,即使进入服务的两条路由运行相同的代码,也许它们正在创建的集线器是独立的并且永远不会作为一个整体进行通信。

然后我想也许我需要一个公共的信号服务器,独立于系统和进程端,两者都可以使用。我创建了一个便笺控制台应用程序,它将充当自主机,然后运行为:

http://localhost:8080

然后我可以重新指向我的脚本标签以查看该 URL,而不是网页端的 ../signalr。

我现在的问题是如何让 WinForms 和 Web 应用程序将正确的上下文注入到服务中?

我尝试为我的服务创建一个构造函数,如下所示:

    private IHubContext<ProcessHub> Clients {get;set;}

    public ProcessService(IHubContext<ProcessHub> clients)
    {
        Clients = clients;
    }

但是我没有使用核心,所以我不知道如何从我的控制器创建和实例化该服务(我通常会在 .net 核心中使用 DI 并注册我的服务)我尝试了这个,但它显然是错误的。 ..

    public ProcessController(IHubContext<ProcessHub> clients)
    {
        _processService = new ProcessService(clients);
    }

这告诉我我需要一个控制器的无参数构造函数。如果我创建其中之一,我想我不能按预期使用该服务。我没有尝试将 win 表单连接到服务,因为我认为我会遇到类似的问题。

任何人都可以帮我解决 a) 我是不是完全找错了树... b) 我如何创建我的服务实例并让它知道我的集线器上下文。

非常感谢!

【问题讨论】:

    标签: .net asp.net-mvc winforms signalr


    【解决方案1】:

    让我向您展示我的解决方案,它正在与我一起工作,我正在使用 asp.NET MVC .net4.6 和winforms .net4.8

    1. 通知中心:
        [HubName("notifyHub")]
        public class NotifyHub : Hub
        {
            public void Send(string name, string message)
            {
                Clients.All.broadcastMessage(name, message);
            }
    
            public Task JoinGroup(string groupName)
            {
                return Groups.Add(Context.ConnectionId, groupName);
    
            }
    
            public Task LeaveGroup(string groupName)
            {
                return Groups.Remove(Context.ConnectionId, groupName);
            }
        }
    
    1. MVC-Controller-Action 向客户端发送消息:
    public ActionResult CreateCustomer(Customer customer)
    {
        if (ModelState.IsValid)
        {
            db.Customers.Add(customer);
            db.SaveChanges();
            var notificationHub = Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<NotifyHub>();
            notificationHub.Clients.Group(YourCustomGroupOfClients.ToString()).UpdateCustomer(customer);
            return RedirectToAction("Index");
        }
    
        return View(customer);
    }
    
    1. 客户端(winforms):
    //  Create this hub globally just one time
    public static HubConnection hubConnection = new HubConnection(baseUrl);
    
    readonly IHubProxy stockTickerHubProxy = Globals.hubConnection.CreateHubProxy("notifyHub");
    
    stockTickerHubProxy.On<Customer>("UpdateCustomer", async customer =>
    {
        try
        {
            var oldCust = await db.Customers.FirstOrDefaultAsync(a => a.id == customer.id);
            if (oldCust == null)
            {
                db.Customer.Add(customer);
            }
            else
            {
                oldCust.Cust_Name = customer.Cust_Name;
                oldCust.Phone1 = customer.Phone1;
            }
            await db.SaveChangesAsync();
            if (InvokeRequired) Invoke(new MethodInvoker(delegate
            {
                Refresh_DG_Customers();
            }));
        }
        catch (Exception)
        {
        }
    });
    

    【讨论】:

    • 谢谢 - 如果从控制器调用他的集线器,此方法可以正常工作。我的问题是服务层负责发送这些消息。我需要在控制器/winforms start 中创建这些连接并以某种方式将它们注入服务
    • 也许this 会帮助你
    猜你喜欢
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 2016-07-21
    • 2021-01-02
    • 1970-01-01
    相关资源
    最近更新 更多