WCF如何绑定netTcpBinding寄宿到控制台应用程序详解

 更新时间:2019-09-08 20:01:25   作者:佚名   我要评论(0)

契约


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

代码如下:


[ServiceContract]
public interface IGameService
{

契约

新建一个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();  } }

服务端配置

在控制台应用程序的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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

果博东方相关的文章

最新评论