简体   繁体   English

使用Web API作为SignalR服务器并从Windows服务中使用它

[英]Using Web API as SignalR server and consuming it from Windows Service

I have a Web application and a Windows Service on the same server the web application communicates with windows service by using .net remoting. 我在Web应用程序通过使用.net远程处理与Windows服务通信的同一服务器上有一个Web应用程序和一个Windows服务。 Windows service checks if the connection with LDAP is working then it returns true else an exception is thrown. Windows服务检查与LDAP的连接是否正常,然后返回true,否则抛出异常。 The status from windows service is updated on website. Windows服务的状态在网站上更新。

Now the infrastructure is going to be changed. 现在基础设施将会发生变化。 The web application is going on Azure and windows service will remain on client's machine (as the LDAP is on the client side). Web应用程序将在Azure上运行,Windows服务将保留在客户端的计算机上(因为LDAP位于客户端)。 I need to update the status on the web application as doing now. 我需要像现在一样更新Web应用程序的状态。 I have introduced Web API as a middle layer between Web Application and Windows Service. 我已经介绍了Web API作为Web应用程序和Windows服务之间的中间层。

I can't find a better solution to achieve this scenario. 我无法找到更好的解决方案来实现这种情况。 I've considerations to use SignalR or Akka.remote. 我考虑使用SignalR或Akka.remote。

What I'm thinking so far, if I use SignalR in Web API and windows service and do the following: 我到目前为止所想的,如果我在Web API和Windows服务中使用SignalR并执行以下操作:

  • Web Application consumes Web API method Web应用程序使用Web API方法
  • Web API method uses SignalR and sends signal to Windows Service Web API方法使用SignalR并向Windows服务发送信号
  • Windows service checks LDAP connectivity and calls Web API method to return the status. Windows服务检查LDAP连接并调用Web API方法以返回状态。

Note: I don't know how we can make Windows Service as a client and make it able to listen if web api sends a signal to it because i don't need to use self hosting for windows service. 注意:我不知道如何将Windows服务作为客户端,并使其能够监听web api是否向其发送信号,因为我不需要为Windows服务使用自托管。 can we use web api as it's already hosted. 我们可以使用web api,因为它已经托管了。

Is it achievable? 它可以实现吗? or is there any better solution? 或者有更好的解决方案吗? Please help. 请帮忙。 Thanks in advance. 提前致谢。

I was been able to workout on this problem and have got the solution. 我能够解决这个问题,并得到了解决方案。

SignalR configuration in startup.cs in Web API Web API中startup.cs中的SignalR配置

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR("/signalr", new Microsoft.AspNet.SignalR.HubConfiguration());
    }
}

In Web API Added Hub 在Web API添加中心

    public class ServiceStatusHub : Hub
    {
        private static IHubContext hubContext = 
        GlobalHost.ConnectionManager.GetHubContext<ServiceStatusHub>();

        public static void GetStatus(string message)
        {
            hubContext.Clients.All.acknowledgeMessage(message);
        }

    }

In Web API Action Method 在Web API操作方法中

    public IEnumerable<string> Get()
    {
        // Query service to check status
        ServiceStatusHub.GetStatus("Please check status of the LDAP!");
        return new string[] { "val1", "val2" };
    }

In Console Application Add SignalR Client 在控制台应用程序中添加SignalR Client

public class SignalRMasterClient
{
    public string Url { get; set; }
    public HubConnection Connection { get; set; }
    public IHubProxy Hub { get; set; }

    public SignalRMasterClient(string url)
    {
        Url = url;
        Connection = new HubConnection(url, useDefaultUrl: false);
        Hub = Connection.CreateHubProxy("ServiceStatusHub");
        Connection.Start().Wait();

        Hub.On<string>("acknowledgeMessage", (message) =>
        {
            Console.WriteLine("Message received: " + message);

            /// TODO: Check status of the LDAP
            /// and update status to Web API.
        });
    }

    public void SayHello(string message)
    {
        Hub.Invoke("hello", message);
        Console.WriteLine("hello method is called!");
    }

    public void Stop()
    {
        Connection.Stop();
    }

}

In Program.cs class 在Program.cs类中

class Program
{
    static void Main(string[] args)
    {
        var client = new SignalRMasterClient("http://localhost:9321/signalr");

        // Send message to server.
        client.SayHello("Message from client to Server!");

        Console.ReadKey();

        // Stop connection with the server to immediately call "OnDisconnected" event 
        // in server hub class.
        client.Stop();
    }
}

Now run the Web API in postman and also run the console app. 现在在postman中运行Web API并运行控制台应用程序。 The two way communication will be established. 将建立双向通信。

Note: The below code is a fix for the issue when console was closed it was not triggering the OnDisconnected event immediately. 注意:下面的代码是修复了控制台关闭时的问题,它没有立即触发OnDisconnected事件。

    public void Stop()
    {
        Connection.Stop();
    }

Check the image showing result. 检查显示结果的图像。

According to your description, you check LDAP connectivity using a Windows service, and you'd like to broadcast LDAP connection status to clients to display updates on web page. 根据您的描述,您使用Windows服务检查LDAP连接,并且您希望向客户端广播LDAP连接状态以在网页上显示更新。 If you integrate SignalR with Web API as a middle layer, you can call that Web API from your Windows service, and you can refer to the following code to broadcast LDAP connection status to clients. 如果将SignalR与Web API集成为中间层,则可以从Windows服务调用该Web API,并且可以参考以下代码将LDAP连接状态广播到客户端。

In Web API controller action 在Web API控制器操作中

var context = Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<ChatHub>();

context.Clients.All.addNewMessageToPage("{new_ LDAP_connectivity}");

Besides, if you can install Microsoft.AspNet.SignalR.Client in your Windows service, you can try to invoke hub method in your Windows service directly, the following code is for your reference. 此外,如果您可以在Windows服务中安装Microsoft.AspNet.SignalR.Client ,您可以尝试直接在Windows服务中调用hub方法,以下代码供您参考。

var hub = new Microsoft.AspNet.SignalR.Client.HubConnection("http://xxxxxx/signalr/hubs");

var proxy = hub.CreateHubProxy("ChatHub");
hub.Start().Wait();

//invoke hub method
proxy.Invoke("addNewMessageToPage", "{new_ LDAP_connectivity}");

Web API method uses SignalR and sends signal to Windows Service Web API方法使用SignalR并向Windows服务发送信号

Please clarify more about this requirement. 请详细说明此要求。 If you'd like to enable clients to fetch and check LDAP connection status records, you can store connections status records in an external storage, and then you can query connections status records from that external storage and push results to clients in your Web API instead of calling the Windows service. 如果要启用客户端以获取和检查LDAP连接状态记录,可以将连接状态记录存储在外部存储中,然后可以从该外部存储查询连接状态记录,并将结果推送到Web API中的客户端调用Windows服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM