简体   繁体   中英

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. Windows service checks if the connection with LDAP is working then it returns true else an exception is thrown. The status from windows service is updated on website.

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). I need to update the status on the web application as doing now. I have introduced Web API as a middle layer between Web Application and Windows Service.

I can't find a better solution to achieve this scenario. I've considerations to use SignalR or Akka.remote.

What I'm thinking so far, if I use SignalR in Web API and windows service and do the following:

  • Web Application consumes Web API method
  • Web API method uses SignalR and sends signal to Windows Service
  • Windows service checks LDAP connectivity and calls Web API method to return the status.

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. can we use web api as it's already hosted.

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

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

In Web API Added Hub

    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

    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

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

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. 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.

    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. 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.

In Web API controller action

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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