zoukankan      html  css  js  c++  java
  • WCF绑定netTcpBinding寄宿到控制台应用程序

    契约

    新建一个WCF服务类库项目,在其中添加两个WCF服务:GameService,PlayerService

    代码如下:

    [ServiceContract]
    public interface IGameService
    {
        [OperationContract]
        Task<string> DoWork(string arg);
    }
    public class GameService : IGameService
    {
        public async Task<string> DoWork(string arg)
        {
            return await Task.FromResult($"Hello {arg}, I am the GameService.");
        }
    }
    [ServiceContract]
    public interface IPlayerService
    {
        [OperationContract]
        Task<string> DoWork(string arg);
    }
    public class PlayerService : IPlayerService
    {
        public async Task<string> DoWork(string arg)
        {
            return await Task.FromResult($"Hello {arg}, I am the PlayerService.");
        }
    }

    服务端

    新建一个控制台应用程序,添加一个类 ServiceHostManager

    public interface IServiceHostManager : IDisposable
    {
        void Start();
        void Stop();
    }
    
    public class ServiceHostManager<TService> : IServiceHostManager
        where TService : class
    {
        ServiceHost _host;
    
        public ServiceHostManager()
        {
            _host = new ServiceHost(typeof(TService));
            _host.Opened += (s, a) => {
                Console.WriteLine("WCF监听已启动!{0}", _host.Description.Endpoints[0].Address);
            };
            _host.Closed += (s, a) =>
            {
                Console.WriteLine("WCF服务已终止!{0}", _host.Description.Endpoints[0].Name);
            };            
        }
        public void Start()
        {
            Console.WriteLine("正在开启WCF服务...{0}", _host.Description.Endpoints[0].Name);
            _host.Open();
        }
        public void Stop()
        {
            if (_host != null && _host.State == CommunicationState.Opened)
            {
                Console.WriteLine("正在关闭WCF服务...{0}", _host.Description.Endpoints[0].Name);
                _host.Close();
            }
        }
        public void Dispose()
        {
            Stop();
        }
    
        public static Task StartNew(CancellationTokenSource cancelTokenSource)
        {
            var theTask = Task.Factory.StartNew(() =>
            {
                IServiceHostManager shs = null;
                try
                {
                    shs = new ServiceHostManager<TService>();
                    shs.Start();
                    while (true)
                    {
                        if (cancelTokenSource.IsCancellationRequested && shs != null)
                        {
                            shs.Stop();
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    if (shs != null)
                        shs.Stop();
                }
            }, cancelTokenSource.Token);
    
            return theTask;
        }
    }

    在Main方法中启动WCF主机

    class Program
        {
            static Program()
            {
                Console.WriteLine("初始化...");
                Console.WriteLine("服务运行期间,请不要关闭窗口。");
                Console.WriteLine();
            }
    
            static void Main(string[] args)
            {
                Console.Title = "WCF主机 x64.(按 [Esc] 键停止服务)";
                var cancelTokenSource = new CancellationTokenSource();
                ServiceHostManager<WcfContract.Services.GameService>.StartNew(cancelTokenSource);
                ServiceHostManager<WcfContract.Services.PlayerService>.StartNew(cancelTokenSource);
                while (true)
                {
                    if (Console.ReadKey().Key == ConsoleKey.Escape)
                    {
                        Console.WriteLine();
                        cancelTokenSource.Cancel();
                        break;
                    }
                }
                Console.ReadLine();
            }
        }
    View Code

    服务端配置

    在控制台应用程序的App.config中配置system.serviceModel

    <system.serviceModel>
        <services>
          <service name="Wettery.WcfContract.Services.GameService" behaviorConfiguration="gameMetadataBehavior">
            <endpoint address="net.tcp://localhost:19998/Wettery/GameService" binding="netTcpBinding" contract="Wettery.WcfContract.Services.IGameService" bindingConfiguration="netTcpBindingConfig">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
          </service>
          <service name="Wettery.WcfContract.Services.PlayerService" behaviorConfiguration="playerMetadataBehavior">
            <endpoint address="net.tcp://localhost:19998/Wettery/PlayerService" binding="netTcpBinding" contract="Wettery.WcfContract.Services.IPlayerService" bindingConfiguration="netTcpBindingConfig">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
          </service>
        </services>
        <bindings>
          <netTcpBinding>
            <binding name="netTcpBindingConfig" closeTimeout="00:30:00" openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="100" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="100" maxReceivedMessageSize="2147483647">
              <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647 " maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <reliableSession ordered="true" inactivityTimeout="00:30:00" enabled="false" />
              <security mode="Transport">
                <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
              </security>
            </binding>
          </netTcpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="gameMetadataBehavior">
              <serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost:8081/Wettery/GameService/MetaData" />
              <serviceDebug includeExceptionDetailInFaults="True" />
              <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
            </behavior>
            <behavior name="playerMetadataBehavior">
              <serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost:8081/Wettery/PlayerService/MetaData" />
              <serviceDebug includeExceptionDetailInFaults="True" />
              <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>

    未避免元数据泄露,部署时将HttpGetEnable设为False

    运行控制台应用程序

    按[ESC]键终止服务

    客户端测试

    服务端运行后,用wcftestclient工具测试,服务地址即behavior中配置的元数据GET地址

    http://localhost:8081/Wettery/GameService/MetaData
    http://localhost:8081/Wettery/PlayerService/MetaData

  • 相关阅读:
    【软件构造】Lab1基本流程指导及重难点分析
    【软件构造】关于java中List和Set数据结构不同实现方式和不同遍历方式时间效率的探讨与分析
    程序人生-Hello’s P2P
    WinterCamp2017吃饭睡觉记
    bzoj 3144 [Hnoi2013]切糕
    bzoj 1565 [NOI2009]植物大战僵尸
    bzoj 1061 [Noi2008]志愿者招募
    序列
    Philosopher
    时机成熟之时
  • 原文地址:https://www.cnblogs.com/felixnet/p/7397139.html
Copyright © 2011-2022 走看看