首页 新闻 会员 周边

一个serviceHost多个wcf服务,为什么宿主为console可以,而windows服务就不行呢?

0
悬赏园豆:50 [已解决问题] 解决于 2014-06-24 17:50

一个serviceHost多个wcf服务,为什么宿主为console可以,而windows服务就不行呢?

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.ServiceModel;
 5 using System.ServiceModel.Activation;
 6 using System.ServiceModel.Web;
 7 using System.Text;
 8 
 9 namespace WcfRestServiceLibrary.Service
10 {
11     [ServiceContract(Namespace = "WcfRestServiceLibrary.Service")]
12     public interface IMicroblogService
13     {
14         [OperationContract]
15         [WebGet(UriTemplate = "")]
16          List<Microblog> GetCollection();
17 
18         [OperationContract]
19         [WebInvoke(UriTemplate = "", Method = "POST", RequestFormat = WebMessageFormat.Json)]
20         Microblog Create(Microblog microblog);
21 
22         [OperationContract]
23         [WebGet(UriTemplate = "{id}",RequestFormat = WebMessageFormat.Xml,ResponseFormat=WebMessageFormat.Json)]
24         Microblog Get(string id);
25 
26         [OperationContract]
27         [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
28         void Delete(string id);
29 
30         [OperationContract]
31         [WebInvoke(Method = "PUT")]
32         void Modify( Microblog microblog);
33     }
34 }
 1 using System;
 2 using System.Runtime.Serialization;
 3 
 4 namespace WcfRestServiceLibrary.Service
 5 {
 6     [DataContract(Namespace = "WcfRestServiceLibrary.Service")]
 7     public class Microblog
 8     {
 9         [DataMember]
10         public int Id { get; set; }
11         [DataMember]
12         public string Content { get; set; }
13         [DataMember]
14         public DateTime PublishTime { get; set; }
15     }
16 
17 
18 }
 1 using System;
 2 using System.Collections.Concurrent;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Net;
 6 using System.ServiceModel;
 7 using System.ServiceModel.Activation;
 8 using System.ServiceModel.Web;
 9 using System.Threading;
10 
11 namespace WcfRestServiceLibrary.Service
12 {
13     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
14     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
15     public class MicroblogService:IMicroblogService 
16     {
17         private static int _currentId;
18         private static IList<Microblog> _microblogs = new List<Microblog> 
19         {
20             new Microblog() {Id=5,Content="Hello,haha",PublishTime =DateTime .Now},
21             new Microblog() {Id=6,Content="test,test",PublishTime =Convert.ToDateTime("2014/03/25")}
22         };
23 
24         public List<Microblog> GetCollection()
25         {
26             return _microblogs.ToList();
27         }
28 
29         public Microblog Create(Microblog microblog)
30         {
31             microblog.Id = Interlocked.Increment(ref _currentId);
32             _microblogs.Add(microblog);
33             return microblog;
34         }
35 
36         public Microblog Get(string id)
37         {
38             Microblog microblog = _microblogs.FirstOrDefault(e => e.Id == int.Parse(id));
39             if(null==microblog)
40             {
41                 WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
42             }
43             return microblog;
44         }
45 
46         public void Delete(string id)
47         {
48             Microblog microblog = Get(id);
49             if(null!=microblog)
50             {
51                 _microblogs.Remove(microblog);
52             }
53             
54         }
55 
56         public void Modify(Microblog microblog)
57         {
58             Delete(microblog.Id.ToString());
59             _microblogs.Add(microblog);
60         }
61 
62     }
63 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Runtime.Serialization;
 6 using System.ServiceModel.Web;
 7 using System.ServiceModel;
 8 
 9 namespace Artech.WcfServices.Service
10 {
11     [ServiceContract]
12     public interface IEmployees
13     {
14         [WebGet(UriTemplate = "all")]
15         IEnumerable<Employee> GetAll();
16 
17         [WebGet(UriTemplate = "{id}")]
18         Employee Get(string id);
19 
20         [WebInvoke(UriTemplate = "/", Method = "POST")]
21         void Create(Employee employee);
22 
23         [WebInvoke(UriTemplate = "/", Method = "PUT")]
24         void Update(Employee employee);
25 
26         [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
27         void Delete(string id);
28     }
29 
30     [DataContract(Namespace = "Artech.WcfServices.Service")]
31     public class Employee
32     {
33         [DataMember]
34         public string Id { get; set; }
35         [DataMember]
36         public string Name { get; set; }
37         [DataMember]
38         public string Department { get; set; }
39         [DataMember]
40         public string Grade { get; set; }
41 
42         public override string ToString()
43         {
44             return string.Format("ID: {0,-5}姓名: {1, -5}级别: {2, -4} 部门: {3}", Id, Name, Grade, Department);
45         }
46     }
47 }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Web;
using System.Net;

namespace Artech.WcfServices.Service
{
public class EmployeesService : IEmployees
{
    private static IList<Employee> employees = new List<Employee>
    {
        new Employee{ Id = "001", Name="张三", Department="开发部", Grade = "G7"},    
        new Employee{ Id = "002", Name="李四", Department="人事部", Grade = "G6"}
    };
    public Employee Get(string id)
    {
        Employee employee = employees.FirstOrDefault(e => e.Id == id);
        if (null == employee)
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
        }
        return employee;
    }
    public void Create(Employee employee)
    {
        employees.Add(employee);
    }
    public void Update(Employee employee)
    {
        this.Delete(employee.Id);
        employees.Add(employee);
    }
    public void Delete(string id)
    {
        Employee employee = this.Get(id);
        if (null != employee)
        {
            employees.Remove(employee);
        }
    }
    public IEnumerable<Employee> GetAll()
    {
        return employees;
    }
}
}

以下是控制台程序,wcf宿主在console:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Configuration;
 4 using System.Linq;
 5 using System.Reflection;
 6 using System.ServiceModel;
 7 using System.ServiceModel.Configuration;
 8 
 9 namespace ConsoleApplication1
10 {
11     class Program
12     {
13         static List<ServiceHost> listHost = null;
14         static ServiceHost host = null;
15         static void Main(string[] args)
16         {
17             //Uri baseAddress = new Uri("http://localhost:8083/MicroblogService");
18             //ServiceHost _host = new ServiceHost(typeof(MicroblogService), baseAddress);
19             
20             ////WebServiceHost _host = new WebServiceHost(typeof(MicroblogService),baseAddress);
21             //using (_host)
22             //{
23             //    ServiceEndpoint endPoint = _host.AddServiceEndpoint(typeof(IMicroblogService), new WebHttpBinding(), baseAddress);
24             //    WebHttpBehavior httpBehavior = new WebHttpBehavior();
25             //    httpBehavior.HelpEnabled = true;
26             //    endPoint.Behaviors.Add(httpBehavior);
27             //    _host.Opened += delegate
28             //    {
29             //        Console.WriteLine("Console Hosted successfully.");
30             //    };
31             //    _host.Open();
32             //    Console.ReadLine();
33             //}
34             //WebServiceHost _host = new WebServiceHost(typeof(MicroblogService));
35             //_host.Opened += delegate
36             //{
37             //    Console.WriteLine("Console Hosted successfully.");
38             //};
39             //_host.Open();
40             //Console.ReadLine();
41 
42             OpenService();
43             Console.ReadLine();
44         }
45 
46         public static void OpenService()
47         {
48             try
49             {
50                 listHost = new List<ServiceHost>();
51                 Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
52 
53                 if (conf != null)
54                 {
55                     ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
56                     foreach (ServiceElement el in svcmod.Services.Services)
57                     {
58 
59                         string klassName = el.Name.Substring(el.Name.LastIndexOf('.') + 1);
60                         Assembly asmb = Assembly.LoadFrom(klassName + ".dll");
61                         Type svcType = asmb.GetType(el.Name);
62 
63                         if (svcType == null)
64                         {
65                             continue;
66                         }
67                         host = new ServiceHost(svcType);
68 
69                         host.Open();
70                         if (!listHost.Contains(host))
71                         {
72                             listHost.Add(host);
73                         }
74                     }
75                 }
76             }
77             catch (Exception ex)
78             {
79                 Console.WriteLine(ex.Message );
80             }
81         }
82     }
83 }

app.config:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <system.serviceModel>
 4     <services>
 5       <!-- This section is optional with the new configuration model
 6            introduced in .NET Framework 4. -->
 7       <service name="WcfRestServiceLibrary.Service.MicroblogService" behaviorConfiguration="MicroblogServiceBehavior">
 8         <host>
 9           <baseAddresses>
10             <add baseAddress="http://127.0.0.1:8034/MicroblogService"/>
11           </baseAddresses>
12         </host>
13         <endpoint address="http://127.0.0.1:8034/MicroblogService"
14                   binding="webHttpBinding"
15                   contract="WcfRestServiceLibrary.Service.IMicroblogService"  behaviorConfiguration="web"/>
16       </service>
17 
18       <service name="Artech.WcfServices.Service.EmployeesService" behaviorConfiguration="EmployeesServiceBehavior">
19         <host>
20           <baseAddresses>
21             <add baseAddress="http://127.0.0.1:3724/EmployeesService"/>
22           </baseAddresses>
23         </host>
24         <endpoint address="http://127.0.0.1:3724/EmployeesService"
25                   binding="webHttpBinding"
26                   contract="Artech.WcfServices.Service.IEmployees" behaviorConfiguration="web"/>
27       </service>
28 
29     </services>
30 
31     <behaviors>
32       <serviceBehaviors>
33         <behavior name="MicroblogServiceBehavior" >
34           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8034/MicroblogService/MetaData"/>
35         </behavior>
36         <behavior name="EmployeesServiceBehavior" >
37           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:3724/EmployeesService/MetaData"/>
38         </behavior>
39       </serviceBehaviors>
40       <endpointBehaviors>
41         <behavior name="web">
42           <webHttp helpEnabled="true" />
43         </behavior>
44       </endpointBehaviors>
45     </behaviors>
46 
47     <!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />-->
48   </system.serviceModel>
49 </configuration>

启动console程序,运行测试:

以上足以证明,控制台程序一启动,两个wcf service都可正常使用了。

但为何host变成windows service就得不到这样的结果呢?

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace WindowsServiceDemo
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new WindowsServiceDemo1() 
            };
            ServiceBase.Run(ServicesToRun);
            //WindowsServiceDemo1 wsd = new WindowsServiceDemo1();
            //wsd.OpenService();
            
        }
    }
}
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Configuration;
  4 using System.Reflection;
  5 using System.ServiceModel;
  6 using System.ServiceModel.Configuration;
  7 using System.ServiceModel.Description;
  8 using System.ServiceModel.Web;
  9 using System.ServiceProcess;
 10 using WcfRestServiceLibrary.Service;
 11 using log4net;
 12 
 13 
 14 namespace WindowsServiceDemo
 15 {
 16     public partial class WindowsServiceDemo1 : ServiceBase
 17     {
 18         /// <summary>
 19         /// 要启动的服务
 20         /// </summary>
 21         List<ServiceHost> listHost = null;
 22         ServiceHost host = null;
 23         private log4net.ILog logger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 24         public WindowsServiceDemo1()
 25         {
 26             InitializeComponent();
 27         }
 28 
 29         protected override void OnStart(string[] args)
 30         {
 31             OpenServices();
 32         }
 33 
 34         public void OpenServices()
 35         {
 36             try
 37             {
 38                 listHost = new List<ServiceHost>();
 39                 Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
 40 
 41                 if (conf != null)
 42                 {
 43                     ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
 44                     foreach (ServiceElement el in svcmod.Services.Services)
 45                     {
 46 
 47                         string klassName = el.Name.Substring(el.Name.LastIndexOf('.') + 1);
 48                         Assembly asmb = Assembly.LoadFrom(klassName + ".dll");
 49                         Type svcType = asmb.GetType(el.Name);
 50 
 51                         if (svcType == null)
 52                         {
 53                             continue;
 54                         }
 55                         host = new ServiceHost(svcType);
 56 
 57                         host.Open();
 58                         if (!listHost.Contains(host))
 59                         {
 60                             listHost.Add(host);
 61                         }
 62                     }
 63                 }
 64             }
 65             catch (Exception ex)
 66             {
 67                 logger.Error(ex.Message);
 68             }
 69         }
 70         protected override void OnStop()
 71         {
 72             CloseServices();
 73         }
 74 
 75 
 76         void CloseServices()
 77         {
 78             try
 79             {
 80 
 81                 if (listHost != null && listHost.Count > 0)
 82                 {
 83 
 84                     foreach (ServiceHost host in listHost)
 85                     {
 86                         if (host != null)
 87                         {
 88                             host.Close();
 89                         }
 90                     }
 91 
 92                 }
 93             }
 94             catch (Exception ex)
 95             {
 96 
 97             }
 98         }
 99     }
100 }


哪位大侠帮帮忙?在此先谢过!

 

 

 

 

 

 

 

Erica Chen的主页 Erica Chen | 初学一级 | 园豆:159
提问于:2014-06-23 09:11
< >
分享
最佳答案
0

通过加入logger日志,发现并解决了问题。

app.config文件内容:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 
 4   <configSections>
 5     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net-net-1.0" />
 6   </configSections>
 7 
 8 
 9   <log4net>
10     <root>
11       <level value="ALL" />
12       <appender-ref ref="LogFileAppender" />
13     </root>
14 
15     <appender name="LogFileAppender"  type="log4net.Appender.FileAppender" >
16       <param name="File" value="Log\log-file.txt" />       
17       <param name="AppendToFile" value="true" />
18       <layout type="log4net.Layout.PatternLayout">
19         <param name="ConversionPattern"  value="记录时间:%d     线程 ID:[%t]    日志级别:%-5p     出错类:%logger property:[%property{NDC}]     错误描述:%m%n" />
20       </layout>
21     </appender>
22   </log4net>
23   <system.serviceModel>
24     <services>
25       <!-- This section is optional with the new configuration model
26            introduced in .NET Framework 4. -->
27       <service name="WcfRestServiceLibrary.Service.MicroblogService" behaviorConfiguration="MicroblogServiceBehavior">
28         <host>
29           <baseAddresses>
30             <add baseAddress="http://127.0.0.1:8033/MicroblogService"/>
31           </baseAddresses>
32         </host>
33         <endpoint address="http://127.0.0.1:8033/MicroblogService"
34                   binding="webHttpBinding"
35                   contract="WcfRestServiceLibrary.Service.IMicroblogService"  behaviorConfiguration="web"/>
36       </service>
37       <service name="Artech.WcfServices.Service.EmployeesService" behaviorConfiguration="EmployeesServiceBehavior">
38         <host>
39           <baseAddresses>
40             <add baseAddress="http://127.0.0.1:3723/EmployeesService"/>
41           </baseAddresses>
42         </host>
43         <endpoint address="http://127.0.0.1:3723/EmployeesService"
44                   binding="webHttpBinding"
45                   contract="Artech.WcfServices.Service.IEmployees" behaviorConfiguration="web"/>
46       </service>
47     </services>
48     
49     <behaviors>
50       <serviceBehaviors>
51         <behavior name="MicroblogServiceBehavior" >
52           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8033/MicroblogService/MetaData"/>
53         </behavior>
54         <behavior name="EmployeesServiceBehavior" >
55           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:3723/EmployeesService/MetaData"/>
56         </behavior>
57       </serviceBehaviors>
58       <endpointBehaviors>
59         <behavior name="web">
60           <webHttp helpEnabled="true" />
61         </behavior>
62       </endpointBehaviors>
63     </behaviors>
64 
65     <!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />-->
66   </system.serviceModel>
67 
68 </configuration>

windows服务程序入口:

 1 using System.ServiceProcess;
 2 
 3 
 4 namespace WindowsServiceDemo
 5 {
 6     static class Program
 7     {
 8         /// <summary>
 9         /// 应用程序的主入口点。
10         /// </summary>
11         static void Main()
12         {
13             ServiceBase[] ServicesToRun;
14             ServicesToRun = new ServiceBase[] 
15             { 
16                 new WindowsServiceDemo1() 
17             };
18             ServiceBase.Run(ServicesToRun);
19         }
20     }
21 }

服务启动需要运行的WindowsServiceDemo1类文件:
注意:WindowsServiceDemo1类命名空间外加了log4net的配置属性。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Configuration;
  4 using System.Reflection;
  5 using System.ServiceModel;
  6 using System.ServiceModel.Configuration;
  7 using System.ServiceProcess;
  8 using log4net;
  9 
 10 [assembly: log4net.Config.DOMConfigurator(ConfigFile = "app.config", Watch = true)]
 11 namespace WindowsServiceDemo
 12 {
 13     public partial class WindowsServiceDemo1 : ServiceBase
 14     {
 15         /// <summary>
 16         /// 要启动的服务
 17         /// </summary>
 18         List<ServiceHost> listHost = null;
 19         ServiceHost host = null;
 20         private log4net.ILog logger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 21 
 22         public WindowsServiceDemo1()
 23         {
 24             InitializeComponent();
 25         }
 26 
 27         protected override void OnStart(string[] args)
 28         {
 29             OpenServices();
 30         }
 31 
 32 
 33         public void OpenServices()
 34         {
 35             try
 36             {
 37                 listHost = new List<ServiceHost>();
 38                 Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
 39                  
 40                 logger.Info("开始启动服务......");
 41                 if (conf != null)
 42                 {
 43                     ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
 44                     foreach (ServiceElement el in svcmod.Services.Services)
 45                     {
 46                         logger.Debug("..."+el.Name );
 47                         string klassName = el.Name.Substring(el.Name.LastIndexOf('.') + 1);
 48                         logger.Debug("..1111." + conf.FilePath.Substring(0, conf.FilePath.LastIndexOf('\\')+1) +  klassName + ".dll");
 49                         Assembly asmb = Assembly.LoadFrom(conf.FilePath.Substring(0, conf.FilePath.LastIndexOf('\\')+1) + klassName + ".dll");
 50                         logger.Debug("..222..." );
 51                         Type svcType = asmb.GetType(el.Name);
 52                         logger.Debug("..333..." + svcType);
 53                         if (svcType == null)
 54                         {
 55                             continue;
 56                         }
 57                         host = new ServiceHost(svcType);
 58                         logger.Info(host.Description.Endpoints[0]);
 59 
 60                         logger.Info(el.Name + ":服务已经启动了");
 61                         host.Open();
 62                         logger.Debug("..444..." );
 63                         if (!listHost.Contains(host))
 64                         {
 65                             logger.Debug("..555...");
 66                             listHost.Add(host);
 67                             logger.Debug("..6666...");
 68                         }
 69                     }
 70                 }
 71                 else
 72                 {
 73                     logger.Warn("没有找到服务对应的配置信息");
 74                 }
 75             }
 76             catch (Exception ex)
 77             {
 78                 logger.Error(ex.Message);
 79             }
 80         }
 81         protected override void OnStop()
 82         {
 83             CloseServices();
 84         }
 85 
 86         void CloseServices()
 87         {
 88             try
 89             {
 90 
 91                 if (listHost != null && listHost.Count > 0)
 92                 {
 93 
 94                     foreach (ServiceHost host in listHost)
 95                     {
 96                         if (host != null)
 97                         {
 98                             host.Close();
 99                         }
100                     }
101 
102                 }
103             }
104             catch (Exception ex)
105             {
106 
107             }
108         }
109     }
110 }

另外ProjectInstaller.cs上两个(serviceInstaller1和serviceProcessInstaller1)组件设置下属性,就不多说了。
然后installutil注册安装服务,启动时修改属性,为本地系统帐户,确保是管理员身份启动,否则无权限访问配置文件中所配置的两个服务的地址

启动服务后,查看运行结果:

Erica Chen | 初学一级 |园豆:159 | 2014-06-24 17:33

想上传整个解决方案源码,却不知道怎么上传

Erica Chen | 园豆:159 (初学一级) | 2014-06-24 17:52
其他回答(3)
0

太长了,可以如下试试:

1)测试OpenServices方法,确保在控制台里能够执行;

2)确保window服务已经启动;

3)跟踪日志,看是否有错误,并在函数里面加上logger.Error(your message)来跟踪;

收获园豆:45
_DN | 园豆:249 (菜鸟二级) | 2014-06-23 11:06

谢谢,加上logger日志,找出原因了!

支持(0) 反对(0) Erica Chen | 园豆:159 (初学一级) | 2014-06-24 17:11

@Erica Chen: 谢谢,一次拿那么多钱给我,我泪流满面啊,哈哈!!!

支持(0) 反对(0) _DN | 园豆:249 (菜鸟二级) | 2014-06-24 18:21
0

Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);

这段代码放在 Windows 服务中运行有问题。

收获园豆:5
Launcher | 园豆:45045 (高人七级) | 2014-06-23 11:25
0

真的好佩服啊

等等小九吧009 | 园豆:172 (初学一级) | 2020-12-01 11:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册