我有一个.NET 4.6应用程序,它承载了一个WCF soap webservice。我使用了100%完全相同的WCF代码和服务定义,唯一不同的是,它是在一个windows服务中运行的,但它没有工作。没有返回任何响应。
因此,例如在.NET 4.6的桌面应用程序中,我可以发送POST soap请求并得到回复,并浏览定义在 http:/10.10.10.10:8904blabla?wsdl 当我在服务账户下以Windows服务的形式运行时,它没有任何反应。例如,浏览到 http:/10.10.10.10:8904blabla?wsdl 不给任何响应(在浏览器中它一直在旋转)。
在netstat中,我可以看到Windows主机在8904端口上,如果我启用WCF跟踪到文件,我可以看到这样的日志,所以至少有一些WCF的活动。
如果我启用WCF跟踪到文件,我可以看到这样的日志,所以至少有一些WCF活动。
<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/DictionaryTraceRecord">
<ActivityName>Ontvang bytes op verbinding http://10.10.10.10:8904/blabla?wsdl.</ActivityName>
<ActivityType>ReceiveBytes</ActivityType>
</ExtendedData>
我已经添加了: netsh http add urlacl url=:http:/+:8904blabla user=Everyone
有什么想法吗?我是不是缺少某些用户权限?作为桌面应用程序和windows服务运行是否需要WCF配置上的差异?
一般来说,桌面应用程序中的托管代码与windows服务中的代码片段是不同的,我们通常使用LocalSystem账户来运行Windows服务,因为WCF服务需要管理员权限来监听机器端口。在OnStart方法中,需要打开服务主机才能监听请求。下面是我的代码段。
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
Uri uri = new Uri("http://localhost:1017");
ServiceHost sh = null;
protected override void OnStart(string[] args)
{
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.None;
try
{
sh = new ServiceHost(typeof(MyService), uri);
sh.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior()
{
HttpGetEnabled = true,
};
sh.Description.Behaviors.Add(smb);
}
Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
sh.Open();
WriteLog($"Service is ready at {DateTime.Now.ToString("hh-mm-ss")}");
}
catch (Exception e)
{
WriteLog($"{DateTime.Now.ToLongDateString()},{DateTime.Now.ToLongTimeString()}-----------------------------------------------------");
WriteLog(e.ToString());
throw;
}
}
protected override void OnStop()
{
if (sh != null && sh.State == CommunicationState.Opened)
{
sh.Close();
WriteLog($"Service is closed at {DateTime.Now.ToString("hh-mm-ss")}");
}
}
public static void WriteLog(string text)
{
using (StreamWriter sw = File.AppendText(@"C:\Mylog.txt"))
{
sw.WriteLine(text);
sw.Flush();
}
}
}
[ServiceContract(Namespace = "mydomain")]
public interface IService
{
[OperationContract]
string SayHello();
}
public class MyService : IService
{
public string SayHello()
{
Service1.WriteLog(string.Format("Wow, I have been called at {0}", DateTime.Now.ToString("hh-mm-ss")));
return $"Hello stranger,Now is {DateTime.Now.ToString()}";
}
}
使用installutil.exe工具安装服务并启动服务后,我们就能够进入服务创建页面。 https:/docs.microsoft.comen-usdotnetframeworkwindows-serviceshow-to-install-and-uninstall-services。如果问题仍然存在,请随时告诉我。
解决方法是从一个单独的线程内启动服务,而不是从主线程启动。否则就会锁死。