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

  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/felixnet/p/7397139.html
Copyright © 2011-2022 走看看