Detecting Client Connection in WCF Long Running Service (Heartbeat implementation) Z

Source: Internet
Author: User

    • Download source-45.3 KB
Introduction

Hello everyone! This is the My first blog on WCF and I hope it.

Today, I'll talk about how to implement heart beat mechanism in WCF, so, whenever client is not alive, our WCF servi Ce detects it and kills its long running process and saves the server resources for other clients.

Background

Basic knowledge of WCF is required.

Using the Code

IMHO, I think there is the no easy-to-detect client have been closed or client is abruptly killed somehow.

Now, I am presenting one scenario and the problem with it and at last, the solution for it.

Scenario

Suppose there is one service which takes lots of time to complete, say 1 hour. And in-between, the client of the WCF service gets killed.

Problem

Then the WCF service would continue to run till the whole method completes their execution, it means full 1 hour. WCF service does not has mechanism to stop its execution when the client is no longer active or alive. It would waste huge server resource and would keep server busy in case resource was scarce on server side.

Solution

Suppose we have a method called "," that would take the 1 hour to complete its DoWork execution.

Hide Copy Code
Interface Ilongrunningservice {     [OperationContract]     Output DoWork ();  }

Now to resolve the problem statement, we had to refactor this method into the below code snippet.

Hide Copy Code
[ServiceContract]     interface ILongRunningServiceV2    {        [operationcontract]        void Startdowork ();        [OperationContract]        Status continueworkandgetstatusfromserver ();        [OperationContract]        Output getfinaldowork ();    } 

Now the method ' DoWork is divided to ' parts, one is ' "and the second is" StartDoWork GetFinalDoWork ".

The client would now call the first method " StartDoWork and return immediately," StartDoWork "would spawn a thread for its execution.

Then client would call the " ContinueWorkAndGetStatusFromServer continuously in while loop with wait ( Thread.Sleep ) of 1 second. This is required because it would keep the server informed that client was still connected to WCF Service and " DoWork " method Execution should not stop. In case client does the " ContinueWorkAndGetStatusFromServer " and then service after few elapsed seconds would stop the execution of " DoWork ”.

In case client keeps calling this method and method " DoWork completes it execution, then the client would call" GetFinalDoWork "to Fetch the result from the service.

This implementation is also called Heart beat implementation.

Now you can see the code snippet below and download the source code.

And this is the original implementation of method " DoWork ".

Hide Copy Code
Class Longrunningservice:ilongrunningservice   {public       Output DoWork ()       {           new StringBuilder ( );           For (Ten; count++) {Builder. Append ("count:" + count); Thread.Sleep (Thenew Output (builder. ToString ()); } }

Now, we had created one SessionManger class for managing the session of active client.

Whenever any client connects to our service, it'll go through the SessionManager class which would maintain the object of ServiceProvider .

ServiceProviderIs our new refactored implementation of method " DoWork ".

Hide Shrink Copy Code
PublicClass ServiceProvider {Private Output _resourceoutput;PrivateReadOnly Status _status;PrivateVolatileBOOL _shoulddisconnect =FalsePrivate Timer _timer;Private DateTime _clientdatetime;Public serviceprovider () {This._status =New Status () {Message ="Initialized ", operationstatus = Operationstatus.none}; }Publicvoid Startdowork () {TimerCallback TimerCallback = stopactivity; _clientdatetime = DateTime.Now; _timer =New Timer (TimerCallback,Null2000,2000); Task.Factory.StartNew (This. runactivity); }Public Status Continueprocessingandgetstatus () {_clientdatetime = DateTime.Now;ReturnThis._status; }Public Output getfinaldowork () {if (This._status. Operationstatus = = Operationstatus.ready) {ReturnThis._resourceoutput; }else {ThrowNew Exception ("Exception "); } }Privatevoid Runactivity () {This._status. Operationstatus = operationstatus.working;var builder =New StringBuilder ();for (int count =0; Count <10; count++) {if (_shoulddisconnect)break; builder. Append ( "count:" + Count); Thread.Sleep (1000); Debug.WriteLine (count); this._status. Message = count. ToString (); } this._status. Operationstatus = Operationstatus.ready; _resourceoutput = new Output (builder. ToString ()); } private void stopactivity ( Object state) {TimeSpan span = DateTime.Now-_clientdatetime; if (span > new TimeSpan (0, 0, 7) {this._timer. Dispose (); _shoulddisconnect = true;} } 

This is a SessionManager class.

Hide Shrink Copy Code
PublicStaticClass sessionmanager<tsessionhandler>where Tsessionhandler:New () {PrivateStaticReadOnly concurrentdictionary<string, tsessionhandler> sessionhandlers =new concurrentdictionary<string, tsessionhandler> (); private static readonly object syncobject = new object (); public static Tsessionhandler getsession () { var sessionId = OperationContext.Current.SessionId; if (Sessionhandlers.containskey (sessionId)) {return Sessionhandlers[sessionid]; } else {lock (syncobject) {Tsessionhandler handler = new Tsessionhandler (); Sessionhandlers.tryadd (sessionId, handler); return handler;} } }}

This is the client code, the method "was an old by- WithNormalService calling and method" WithVersion2Service "is a new-to-a-calling service.

Hide Shrink Copy Code
Staticvoid Withnormalservice () {longrunningserviceclient client =New Longrunningserviceclient ();var result = client.        DoWork (); Console.WriteLine (Result.    Finalvalue); }static void Withversion2service () { Longrunningservicev2client client = new longrunningservicev2client (), client. Startdowork (); string servicemsg = string. Empty; Status Status = Client. Continueworkandgetstatusfromserver (); Console.WriteLine (status. Operationstatus); do {if (!string. IsNullOrEmpty (status. Message) {if (status. Message) {servicemsg = status. Message; Console.Out.WriteLine (status. Message); }} thread.sleep (500); status = Client. Continueworkandgetstatusfromserver (); } while (status. Operationstatus! = Operationstatus.ready); Servicereferencev2.output image = Client. Getfinaldowork (); Console.WriteLine (image. Finalvalue); }

Earlier, this is the flow of calling between client and service.

Client--->DoWork

Now after the implementation of Heartbeat in WCF service, this is the new from calling WCF service.

Client--->StartDoWork

Client---> ContinueWorkAndGetStatusFromServer in a while loop till it get Operation Status ready and then it'll call GetFinalDoWork .

Client--->GetFinalDoWork

Point of Interest

One improvement point in this code was to remove the dead client references from the dictionary in SessionManager class.

Detecting Client Connection in WCF Long Running Service (Heartbeat implementation) Z

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.