WCF通讯实现

你好呀嗯嗯 / 2024-10-21 / 原文

1.服务端实现:

一.创建接口,并附加ServiceContract特性,并添加回调接口

namespace SOA.WCF.Interface
{
    [ServiceContract(CallbackContract =typeof(ICallBack))]
    public interface ICalculatorService
    {
        [OperationContract(IsOneWay =true)]
        void Plus(int x, int y);
    }
}
namespace SOA.WCF.Interface
{
    /// <summary>
    /// 不需要协议  是一个约束,由客户端实现
    /// </summary>
    public interface ICallBack
    {
        [OperationContract(IsOneWay =true)]
        void Show(int m,int n,int result);
    }
}

二.实现接口;

namespace SOA.WCF.Service
{
    public class CalculatorService : ICalculatorService
    {
        public void Plus(int x, int y)
        {
            //return x + y;
            int result = x + y;

            ICallBack callBack = OperationContext.Current.GetCallbackChannel<ICallBack>();
            callBack.Show(x,y,result);
        }
    }
}

三.配置config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <system.serviceModel>
        <!--<behaviors>
            <serviceBehaviors>
                <behavior name="MathServicebehavior">
                    <serviceDebug httpHelpPageEnabled="false"/>
                    <serviceMetadata httpGetEnabled="false"/>
                    <serviceTimeouts transactionTimeout="00:10:00"/>
                    <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="httpbinding"/>
            </basicHttpBinding>
        </bindings>
        <services>
            <service name ="SOA.WCF.Service.MathService" behaviorConfiguration="MathServicebehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:11113/MathService"/>
                        
                    </baseAddresses>
                </host>
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="httpbinding" contract="SOA.WCF.Interface.IMathService"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>-->


        <!--<behaviors>
            <serviceBehaviors>
                <behavior name="MathServicebehavior">
                    <serviceDebug httpHelpPageEnabled="false"/>
                    <serviceMetadata httpGetEnabled="false"/>
                    <serviceTimeouts transactionTimeout="00:10:00"/>
                    <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>

        <bindings>
            <netTcpBinding>
                <binding name="tcpbinding">
                    <security mode="None">
                        <transport clientCredentialType="None" protectionLevel="None"/>
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>

        <services>
            <service name ="SOA.WCF.Service.MathService" behaviorConfiguration="MathServicebehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:1111/MathService"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="SOA.WCF.Interface.IMathService"/>
                <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
            </service>
        </services>-->

        <behaviors>
            <serviceBehaviors>
                <behavior name="MathServicebehavior">
                    <serviceDebug httpHelpPageEnabled="false"/>
                    <serviceMetadata httpGetEnabled="false"/>
                    <serviceTimeouts transactionTimeout="00:10:00"/>
                    <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
                </behavior>

                <behavior name="CalculatorServicebehavior">
                    <serviceDebug httpHelpPageEnabled="false"/>
                    <serviceMetadata httpGetEnabled="false"/>
                    <serviceTimeouts transactionTimeout="00:10:00"/>
                    <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>

        <bindings>
            <netTcpBinding>
                <binding name="tcpbinding">
                    <security mode="None">
                        <transport clientCredentialType="None" protectionLevel="None"/>
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>

        <services>
            <service name ="SOA.WCF.Service.MathService" behaviorConfiguration="MathServicebehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:1111/MathService"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="SOA.WCF.Interface.IMathService"/>
                <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
            </service>

            <service name ="SOA.WCF.Service.CalculatorService" behaviorConfiguration="CalculatorServicebehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:1111/CalculatorService"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="SOA.WCF.Interface.ICalculatorService"/>
                <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
            </service>
        </services>

    </system.serviceModel>
</configuration>

4.启动服务:

 public static void Process()
        {
            List<ServiceHost> hosts = new List<ServiceHost>()
            {
                new ServiceHost(typeof(MathService)),
                new ServiceHost(typeof(CalculatorService))
            };

            foreach (var host in hosts)
            {
                host.Opening += (s, e) => Console.WriteLine($"{host.GetType().Name} 打开");
                host.Open();
            }

            Console.WriteLine("输入任何字符,就停止");
            Console.Read();
            foreach (var host in hosts)
            {
                host.Close();
            }
            Console.Read();
}

5.客户端调用如下:

一.添加服务引用:

二.进行调用

namespace SOA.ConsoleTestProject
{
    class Program
    {
        static void Main(string[] args)
        {
            CallBackWCFTest.CalculatorServiceClient client = null;
            try
            {
                Console.WriteLine("This is test project");
                InstanceContext context = new InstanceContext(new CallBackService());
                client = new CallBackWCFTest.CalculatorServiceClient(context);
                client.Plus(1, 2);
                client.Close();
                Console.Read();
            }
            catch(Exception ex)
            {
                if(client != null)
                {
                    client.Abort();
                }
                Console.WriteLine(ex.Message);
            }
        }
    }

回调方法实现

namespace SOA.ConsoleTestProject
{
    class CallBackService : CallBackWCFTest.ICalculatorServiceCallback
    {
        public void Show(int m, int n, int result)
        {
            Console.WriteLine($"回调:{m}+{n}={result}");
        }
    }
}

当在服务端进行Show方法的调用时,客户端会进入show方法中执行,这样一来,就实现了服务端发消息给客户端;