简体   繁体   中英

Push notifications to client with SignalR,WCF duplex service and ASP.Net generic handler?

I should use a developed WCF duplex service to send file to a specified IP address, So I have some call back operations they should be used as notifications in client side, I came to this conclusion to use SignalR but I am newbie in SignalR for this reason don't actually know SignalR can be a good fit to do this or not.

Let see what codes I am working on, in ASP.Net generic handler my "SendToServer" action and using the WCF client proxy is as following:

SendClient sendClient = new SendClient(new SendCallback(),new System.ServiceModel.NetTcpBinding(),new System.ServiceModel.EndpointAddress(endPointAddress)); 
        sendClient.OperationFailed += sendClient_OperationFailed;
        sendClient.OperationTimedOut += sendClient_OperationTimedOut;
        sendClient.SendingFinished += sendClient_SendingFinished;
        sendClient.ConnectionClosed += sendClient_ConnectionClosed;
        sendClient.ConnectionRefused += sendClient_ConnectionRefused;
        sendClient.InstanceStored += sendClient_InstanceStored;
sendClient.Send(/*Array of resources ids*/,  /*Server instance*/);

and my event handlers are as following:

public void sendClient_InstanceStored(object sender, int currentInstance, int totalInstance, int currentStudy, int TotalStudy)
    { 
        //Get fired when one file successfully sent
    } 
    public void sendClient_ConnectionRefused(object sender, EventArgs e)
    {
        //Connection refused
    }

    public void sendClient_ConnectionClosed(object sender, EventArgs e)
    {
        //Connection closed
    }

    public void sendClient_SendingFinished(object sender, EventArgs e)
    {
        //Sending finished
    }

    public void sendClient_OperationTimedOut(object sender, EventArgs e)
    {
        //Operation timed out
    }

    public void sendClient_OperationFailed(object sender, EventArgs e)
    {
        //Operation failed
    }

And calling this action in JS is as following:

 $.ajax({
            cache: false,
            type: "POST",
            url: '../Handlers/Study/Send.ashx',
            dataType: "json",
            data: {
                Action: "SendToServer",
                Hostname: DeviceHostname, Port: DevicePort, Description: Description, Ids2Send: JSON.stringify(rows)
            },
            async: true,
            success: function (data) {
                if (data.Success == false) {
                    $("#loader-Send").remove();
                    $(".ui-dialog-buttonpane button:contains('Send')").button("enable");
                    showNoticeMessage("Can not send to Server!");
                    return;
                }
            },
            error: function (x, e) {
                $("#loader-Send").remove();
                $(".ui-dialog-buttonpane button:contains('Send')").button("enable");
                showNoticeMessage("Can not send to Server!");
            }
        });

Is it possible to use that event handlers as notification by SignalR in client-side after starting $.ajax ?

or

Is there another way(s) to do this without using SignalR and how?

Thanks in advance.

If someone needs here is the solution:

1- SignalR should be installed.

2- Make an Owin startup class like :

   public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        app.MapSignalR();
    }
}

3- Define and implement your own notification class like:

[HubName("sendNotifier")]
public class SendNotifier : Hub
{
    public string CurrentConnectionID { get; set; }
    public void SendStarted()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendStarted();
    }
    public void SendFailed()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendFailed();
    }
    public void InstanceStored(int currentInstance, int totalInstance, int currentStudy, int totalStudy)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).instanceStored(currentInstance, totalInstance, currentStudy, totalStudy);
    }
    public void SendFinished()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).sendFinished();
    }
    public void ConnectionClosed()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionClosed();
    }
    public void ConnectionTimedOut()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionTimedOut();
    }
    public void ConnectionRefused()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionRefused();
    }

    public void ConnectionFailed()
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<SendNotifier>();
        if (CurrentConnectionID != null)
            context.Clients.Client(CurrentConnectionID).connectionFailed();
    }
}

4- In event handlers we can call our notification method for example

 public void sendClient_ConnectionEstablished(object sender, EventArgs e)
    {
        SendNotifier sendNotifier = new SendNotifier();
        sendNotifier.CurrentConnectionID = ClientID;
        sendNotifier.SendStarted();
    }

Note: I am pasing ClientID within Ajax request.

And Client side code:

 var hub = $.connection.sendNotifier;
    hub.client.sendStarted = function () {

    };

    hub.client.sendFinished = function () {
    };

    hub.client.sendFailed = function () {
    };
    //var temp;
    hub.client.instanceStored = function (currentInstance, totalInstance, currentStudy, totalStudy) {
    };

    hub.client.connectionClosed = function () {
    };

    hub.client.connectionTimedOut = function () {
    };

    hub.client.connectionRefused = function () {
    };

    hub.client.connectionFailed = function () {
    };

    $.connection.hub.logging = true;
    $.connection.hub.start().done(function () {
    });

And ClientID : ClientID: $.connection.hub.id

SignalR and it's stuff should be referenced in head of page.

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