Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 609
Imran Yaseen Avatar asked Sep 22 '17 11:09

Imran Yaseen


People also ask

Can SignalR be used in Web API?

SignalR can be used together with Web API just fine, so some functionality in application which is not realtime and doesn't require persistent connection could be served by Web API.

Can we use SignalR in Windows application?

SignalR. Client45 to use in your application. It works for WPF, WF or even console applications. And even if it didn't, SignalR is just a wrapper around the WebSockets protocol, which is part of the HTTP protocol, which can be used on virtually any platform.


1 Answers

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.

like image 146
Imran Yaseen Avatar answered Sep 22 '22 01:09

Imran Yaseen