Tuesday, June 16, 2015

Progress Notification for Long Running Methods using WCF Duplex Binding, SignalR

Hi Guys,

This time I made a WCF Duplex Service which notifies the progress to the client using SingalR. Hope you like it.













Windows Client









1) ServiceClient.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ServiceClient.aspx.cs" Inherits="Htm5Notifications.ServiceClient" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="../Scripts/jquery-1.6.4.js"></script>    
    <script src="../Scripts/jquery.signalR-2.2.0.js"></script>
    <script src="http://localhost:51255/signalr/hubs/" type="text/javascript"></script>
    <script src="Message.js"></script>
    <link href="../Styles/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input type="hidden" id="hfHubName" value="<%= string.Format("#{0}",hfHubId.ClientID) %>" />
        <asp:HiddenField ID="hfHubId" runat="server" />
    <div class="progress">
  <div id="progressBar" class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
  aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:10%" >
   
  </div>
</div>
        <br />
        <asp:Button runat="server" CssClass="btn-primary" ID="btnStart" OnClick="btnStart_Click" Text="Start Long Process" />
    </div>
    </form>
</body>

</html>

2) DuplexService.svc.cs

public class DuplexService : IDuplexService
    {
        public void DoWork()
        {
            for (int i = 0; i < 100; i++)
            {
                System.Threading.Thread.Sleep(1000);
                Callback.Progress(i + 1);
            }
        }

        IDuplexServiceCallback Callback
        {
            get
            {
                return OperationContext.Current.GetCallbackChannel<IDuplexServiceCallback>();
            }
        }

    }

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required,
                 CallbackContract = typeof(IDuplexServiceCallback))]
    public interface IDuplexService
    {
        [OperationContract(IsOneWay = true)]
        void DoWork();
    }

   public interface IDuplexServiceCallback
   {
       [OperationContract(IsOneWay = true)]
       void Progress(int percentage);
       

   }

3) MessageHub.cs

[HubName("messageHub")]
    public class MessageHub : Hub
    {

     
        [HubMethodName("setPercentage")]
        public static void SetPercentage(string cId,string percentage)
        {

            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MessageHub>();
            context.Clients.All.setPercentage(cId,percentage);

        }   


    }

4) Message.js
/// <reference path="../Scripts/jquery-1.6.4.js" />
/// <reference path="../Scripts/jquery.signalR-2.2.0.js" />


$(function () {

    //Instance of the Hub
    
    function setPercent(cid, percent)
    {
        alert($($('#hfHubName').val()).val());
        alert(cid);
        if ($($('#hfHubName').val()).val() == cid) {
            $('#progressBar').text(percent + "% Completed!");
            $('#progressBar').attr("aria-valuenow", percent);
            $('#progressBar').css("width", percent + "%");
        }
    }

    var messageHub = $.connection.messageHub;
    messageHub.client.showMessage = function (cpu, mem, proc, thread, cmem, memUse) {
        show(cpu, mem,proc, thread,cmem,memUse);
    }

    messageHub.client.setPercentage = function (cid, percentage)
    {
        setPercent(cid, percentage);
    }

    $.connection.hub.url = "http://localhost:51255/signalr";
    $.connection.hub.start().done(function () {
        if ($($('#hfHubName').val()).val() == '')
        $($('#hfHubName').val()).val($.connection.hub.id);
        
    }).fail(function (error) {
        console.error(error);
    });;


    

});