《WCF开发日志 -- WCF启动多个服务.pdf》由会员分享,可在线阅读,更多相关《WCF开发日志 -- WCF启动多个服务.pdf(16页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、WCF 开发日志-WCF 启动多个服务场景:项目比较大,不可能所有契约在一个类里来实现,可能会有上百个服务上千个契约,按照目前在网上搜索的结果是.只能一个 servicehost 对应一个服务,某个 mvp 的建议是所有契约都放到一个类里来实现。我崩溃。想法:也有人建议用 partial class 的方式,把不同的契约分布到不同的 CS 文件里,虽然可能看上去好一点,但每回添加服务都得重编译,我觉得太扯淡了。我希望是尽可能的把服务根据功能的不同按模块划分开来,不同的服务做成不同的 dll,以插件的形式注册到一个表里,用 servicehost 来加载,不知大家有没有好的建议。其实可以考虑用
2、CSLA.NET 的方案,只写一个服务,它称为统一入口,这个方式还是不错的,就是他为解决并发,并发好像在博客园里有人写了怎么实现,地址是http:/ Windows 中 Host 多个 WCF 服务?2、不能是多个 Open 方法,那样太幼稚了!3、考虑到整个团队都不会 CSLA.NET,或 OEA 就我会一点:),这个还的多谢周哥,和 胡总 的栽培了。4、整个团队学习成本太高,只有不断的分享,讨论来加快进度了。二、本文大纲a、摘要。b、本文大纲。c、项目准备阶段。d、主要核心代码。e、达到的效果图。三、项目准备阶段这个图需要一点 C#基础才能看的懂的:)估计一上图大家就看的懂(自己想象中.)
3、了。这里主要是创建 Windows 项目和 WCF Service Library项目Windows 项目还需要引用 WCF Service Library 项目四、主要核心代码运行按钮事件代码:1:private void button1_Click(object sender,EventArgs e)2:3:if(button1.Tag=run)4:5:ServiceStart();6:button1.Text=停止(&X);7:button1.Tag=stop;8:9:else10:11:button1.Text=运行(&R);12:button1.Tag=run;13:
4、14:15:ServiceStart()函数代码:1:private List<ServiceHost>serviceHosts=newList<ServiceHost>();2:private void ServiceStart()3:4:5:#region 初?始?化 serviceHosts6:if(serviceHosts!=null)7:8:foreach(ServiceHost t in serviceHosts)9:10:if(t!=null)11:t.Close();12:13:14:else15:16:serviceHosts=newList<S
5、erviceHost>();17:18:#endregion19:20:string serviceAddress=string.Format(net.tcp:/0:1,127.0.0.1,8000);21:22:Dictionary<Type,Type>sevtypes=newDictionary<Type,Type>();23:sevtypes.Add(typeof(IService1),typeof(Service1);24:sevtypes.Add(typeof(IService2),typeof(Service2);25:26:string endpoi
6、ntAddress=string.Empty;27:string tName=string.Empty;28:StringBuilder msgService=newStringBuilder();29:foreach(var item in sevtypes)30:31:tName=item.Key.Name.Substring(1);32:endpointAddress=serviceAddress+tName;33:if(!serviceAddress.EndsWith(/)34:endpointAddress=string.Format(0/1,serviceAddress,tName
7、);35:ServiceHost serviceHost=newServiceHost(item.Value,new Uri(endpointAddress);36:37:/加载元数据结点38:ServiceMetadataBehavior smb=newServiceMetadataBehavior();39:serviceHost.Description.Behaviors.Add(smb);40:serviceHost.AddServiceEndpoint(typeof(IMetadataExchange),MetadataExchangeBindings.CreateMexTcpBin
8、ding(),mex);41:/加载 NetTcpBinding 结点42:NetTcpBinding netTcpBinding=newNetTcpBinding();43:netTcpBinding.Security.Mode=SecurityMode.None;44:netTcpBinding.ReceiveTimeout=TimeSpan.Parse(00:10:00);45:netTcpBinding.MaxBufferPoolSize=2147483647;46:netTcpBinding.MaxBufferSize=2147483647;47:netTcpBinding.MaxC
9、onnections=10;48:49:netTcpBinding.ReaderQuotas.MaxDepth=2147483647;50:netTcpBinding.ReaderQuotas.MaxStringContentLength=2147483647;51:netTcpBinding.ReaderQuotas.MaxArrayLength=2147483647;52:netTcpBinding.ReaderQuotas.MaxBytesPerRead=2147483647;53:netTcpBinding.ReaderQuotas.MaxNameTableCharCount=2147
10、483647;54:netTcpBinding.MaxReceivedMessageSize=2147483647;55:serviceHost.AddServiceEndpoint(item.Key,netTcpBinding,endpointAddress);56:57:serviceHost.Opened+=delegate58:59:msgService.AppendLine(string.Format(0开始监听 Uri为:1/mex,tName,endpointAddress.ToString();60:;61:62:serviceHost.Open();63:serviceHos
11、ts.Add(serviceHost);64:65:this.textBox1.Text=msgService.ToString();66:67:代码约定:每次增加服务和契约的时候都需要同时添加 Dictionary要不然系统不会启动新增加的服务。服务地址:net.tcp:/127.0.0.1:8000/服务名/mex上面的例子生成如下地址:net.tcp:/127.0.0.1:8000/Service1/mexnet.tcp:/127.0.0.1:8000/Service2/mex把”Dictionary”改成配置文件形式,也就通用了。网上的一个使用配置文件的例子:配置文件如下:1:<
12、system.serviceModel>2:<services>3:<servicename=ChinaQueue.Restaurant.WCFService.ServiceImplementations.PrinterSer behaviorConfiguration=sb>4:<host>5:<baseAddresses>6:<addbaseAddress=net.tcp:/localhost:8081/>7:</baseAddresses>8:</host>9:<endpointname=Ne
13、tTcpBinding_IPrinterServeraddress=PrinterSer binding=netTcpBindingbindingConfiguration=NetTcpBinding_IServercontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.IPrinterSer/>10:<endpointname=MexTcpBinding_IPrinterServer address=Printerbinding=mexTcpBinding contract=IMetadataExchange/>
14、11:</service>12:<servicename=ChinaQueue.Restaurant.WCFService.ServiceImplementations.CounterSer behaviorConfiguration=sb>13:<host>14:<baseAddresses>15:<addbaseAddress=net.tcp:/localhost:8081/>16:</baseAddresses>17:</host>18:<endpointname=NetTcpBinding_ICo
15、unterServeraddress=CounterSer binding=netTcpBindingbindingConfiguration=NetTcpBinding_IServercontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.ICounterSer/>19:<endpointname=MexTcpBinding_ICounterServeraddress=Counter binding=mexTcpBindingcontract=IMetadataExchange/>20:</service&
16、gt;21:<servicename=ChinaQueue.Restaurant.WCFService.ServiceImplementations.QuerySer behaviorConfiguration=sb>22:<host>23:<baseAddresses>24:<addbaseAddress=net.tcp:/localhost:8081/>25:</baseAddresses>26:</host>27:<endpointname=NetTcpBinding_IQueryServeraddress=Q
17、uerySer binding=netTcpBindingbindingConfiguration=NetTcpBinding_IServercontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.IQuerySer/>28:<endpointname=MexTcpBinding_IQueryServer address=Querybinding=mexTcpBinding contract=IMetadataExchange/>29:</service>30:</services>31:&
18、lt;behaviors>32:<serviceBehaviors>33:<behavior name=sb>34:<serviceMetadata/>35:<serviceDebugincludeExceptionDetailInFaults=true/>36:</behavior>37:</serviceBehaviors>38:</behaviors>39:<bindings>40:<netTcpBinding>41:<bindingname=NetTcpBinding
19、_IServer>42:<readerQuotas maxDepth=32maxStringContentLength=8192maxArrayLength=16384 maxBytesPerRead=4096maxNameTableCharCount=16384/>43:<reliableSession ordered=trueinactivityTimeout=00:10:00 enabled=false/>44:<security mode=None>45:<transportclientCredentialType=Windowsprot
20、ectionLevel=EncryptAndSign/>46:<messageclientCredentialType=Windows/>47:</security>48:</binding>49:</netTcpBinding>50:</bindings>51:<client>52:<endpointaddress=net.tcp:/localhost:8081/PrinterSerbinding=netTcpBindingbindingConfiguration=NetTcpBinding_IServerc
21、ontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.IPrinterSername=NetTcpBinding_IPrinterServer/>53:<endpointaddress=net.tcp:/localhost:8081/CounterSerbinding=netTcpBindingbindingConfiguration=NetTcpBinding_IServercontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.ICounterSernam
22、e=NetTcpBinding_ICounterServer/>54:<endpointaddress=net.tcp:/localhost:8081/QuerySerbinding=netTcpBindingbindingConfiguration=NetTcpBinding_IServercontract=ChinaQueue.Restaurant.WCFService.ServiceContracts.IQuerySer name=NetTcpBinding_IQueryServer/>55:</client>56:</system.serviceMo
23、del>57:以上是三个服务的配置,然后在 Main 方法中 Host 这三个服务,以下是如何从配置文件中读取服务并进行 Host 的System.ServiceModel.Configuration1:Configuration conf=ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);2:ServiceModelSectionGroup svcmod=(ServiceModelSectionGroup)conf.GetSectionGroup(system.serviceM
24、odel);3:foreach(ServiceElement el insvcmod.Services.Services)4:5:Type svcType=Type.GetType(el.Name+,+ChinaQueue.Restaurant.WCFService);6:if(svcType=null)7:throw new Exception(InvalidService Type +el.Name+in configuration file.);8:ServiceHost aServiceHost=newServiceHost(svcType);9:aServiceHost.Open();10:11:五、达到的效果图测试通过,有图作证:这个服务启动成功了,客服端也测试通过,耶搞定。