• 【转】一个简单的WCF回调实例


    代码下载:http://files.cnblogs.com/AlwinXu/CallbackService-master.zip 

    本文转自:

    http://adamprescott.net/2012/08/15/a-simple-wcf-service-callback-example/

    A Simple WCF Service Callback Example

    11 Replies

    I’ve done a lot with WCF services over the past few years, but I haven’t done much with callbacks. I wanted to write a simple application to understand and demonstrate how a callback service works in WCF. The example described below was implemented in a single solution with two console application projects, one client and one server.

                           

    Create the server

    The first thing we’ll do is create and host our WCF service. This will be done in five short steps:

    1. Create      the service contract
    2. Create      the service callback contract
    3. Create      the service implementation
    4. Modify      the endpoint configuration
    5. Host      the service

    To create the service contract, service implementation, and default endpoint configuration, you can use Visual Studio’s menu to choose Add New Item > Visual C# Items > WCF Service. I named my service MyService, and so my service contract is called IMyService. Visual Studio creates the service contract with a single method, DoWork. I decided that I wanted my service to have two methods: OpenSession and InvokeCallbackOpenSession will be used by the server to store a copy of the callback instance, and InvokeCallback will be used to trigger a callback call to the client from the client.

    Here’s my complete IMyService contract:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    using System.ServiceModel;

    namespace CallbackService.Server

    {

        [ServiceContract(CallbackContract   = typeof(IMyServiceCallback))]

        public interface IMyService

        {

            [OperationContract]

            void OpenSession();

        }

    }

    Note that the service contract indicates the callback contract in its attribute. The callback contract, IMyServiceCallback, will have a single method, OnCallback. Here is the complete IMyServiceCallback interface:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    using System.ServiceModel;

    namespace CallbackService.Server

    {

        public interface IMyServiceCallback

        {

            [OperationContract]

            void OnCallback();

        }

    }

    The third step requires us to implement our service. When OpenSession is called, I create a timer that will invoke the callback once per second. Note the ServiceBehavior attribute that sets the ConcurrencyMode to Reentrant. If you do not change the ConcurrencyMode to Multiple or Reentrant, the channel will be locked and the callback will not be able to be invoked. Here is the complete MyService implementation:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    using System;

    using System.ServiceModel;

    using System.Timers;

    namespace CallbackService.Server

    {

        [ServiceBehavior(ConcurrencyMode   = ConcurrencyMode.Reentrant)]

        public class MyService   : IMyService

        {

            public static IMyServiceCallback   Callback;

            public static Timer   Timer;

            public void OpenSession()

            {

                Console.WriteLine(">   Session opened at {0}", DateTime.Now);

                Callback   = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();

                Timer   = new Timer(1000);

                Timer.Elapsed   += OnTimerElapsed;

                Timer.Enabled   = true;

            }

            void OnTimerElapsed(object sender,   ElapsedEventArgs e)

            {

                Callback.OnCallback();

            }

        }

    }

    When we added the new WCF service to the project, Visual Studio added the default endpoint configuration to the app.config. By default, wsHttpBinding is used as the binding. We want to change it to use wsDualHttpBinding which supports two-way communication. I also changed the URL to be friendlier, but that is not necessary. Here’s my final app.config:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

      <system.serviceModel>

        <behaviors>

          <serviceBehaviors>

            <behavior name="">

              <serviceMetadata httpGetEnabled="true" />

              <serviceDebug includeExceptionDetailInFaults="false" />

            </behavior>

          </serviceBehaviors>

        </behaviors>

        <services>

          <service name="CallbackService.Server.MyService">

            <endpoint address="" binding="wsDualHttpBinding" contract="CallbackService.Server.IMyService">

              <identity>

                <dns value="localhost" />

              </identity>

            </endpoint>

            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

            <host>

              <baseAddresses>

                <add baseAddress="http://localhost:8090/CallbackService.Server/MyService/" />

              </baseAddresses>

            </host>

          </service>

        </services>

      </system.serviceModel>

    </configuration>

    The final step is to simply host the service. Since my server is a console application, I do this in the Program.Main method. Here is the complete class:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    using System;

    using System.ServiceModel;

    namespace CallbackService.Server

    {

        class Program

        {

            static void Main(string[]   args)

            {

                var host   = new ServiceHost(typeof(MyService));

                host.Open();

                Console.WriteLine("Service   started at {0}", DateTime.Now);

                Console.WriteLine("Press   key to stop the service.");

                Console.ReadLine();

                host.Close();

            }

        }

    }

    Create the client

    With the server complete, creating the client is a breeze. We’ll complete the client in just three steps:

    1. Add      a service reference
    2. Implement      the callback class
    3. Create      the client proxy

    To add the service reference, you must have the service running. I did this by simply running the server executable outside of Visual Studio. You can copy the URL from the server’s app.config. Right-click References in your client project, choose Add Service Reference, and paste the URL. I named my service reference MyServiceReference.

    The service reference pulls in IMyServiceCallback, which will allow us to create our callback class. To do this, just add a new, empty class to the project. I named my class MyServiceCallback, and when the callback is invoked, it just writes a line to the console. Here is the complete implementation:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    using System;

    using CallbackService.Client.MyServiceReference;

    namespace CallbackService.Client

    {

        public class MyServiceCallback   : IMyServiceCallback

        {

            public void OnCallback()

            {

                Console.WriteLine(">   Received callback at {0}", DateTime.Now);

            }

        }

    }

    The client application is also a console application, so creating and using the proxy client will occur in its Program.Main. I added a pause to allow the server time to host the service, and then I invoke the remote procedure OpenSession. This will trigger the service to begin executing callbacks to the client application every second, resulting in a line written to the console. Here’s is the contents of my Program.cs:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    using System;

    using System.ServiceModel;

    namespace CallbackService.Client

    {

        class Program

        {

            static void Main(string[]   args)

            {

                Console.WriteLine("Press   enter to continue once service is hosted.");

                Console.ReadLine();

                var callback   = new MyServiceCallback();

                var instanceContext   = new InstanceContext(callback);

                var client   = new MyServiceReference.MyServiceClient(instanceContext);

                client.OpenSession();

                Console.ReadLine();

            }

        }

    }

    Conclusion

    And that’s all there is to it! This is clearly a simple, unorganized example with few complexities, but it demonstrates the core functionality provided by callbacks in WCF services. This capability allows for push updates and other real-time communication between client and server, and it really opens a world of possibilities. This is certainly a welcome option in my ever-growing development toolbox!

  • 相关阅读:
    【小白的CFD之旅】14 实例反思
    【小白的CFD之旅】13 敲门实例【续3】
    【小白的CFD之旅】12 敲门实例【续2】
    【小白的CFD之旅】11 敲门实例【续】
    【小白的CFD之旅】10 敲门实例
    【小白的CFD之旅】09 初识FLUENT
    【小白的CFD之旅】08 CFD速成之道
    【小白的CFD之旅】07 CFD常识
    【小白的CFD之旅】06 流体力学基础
    软件工程-构建之法 理解C#一小段程序
  • 原文地址:https://www.cnblogs.com/AlwinXu/p/4228742.html
Copyright © 2020-2023  润新知