简体   繁体   English

WCF:自托管NetTcp服务,无法解析

[英]WCF: Self-host a NetTcp service, doesn't resolve

I am trying to host a WCF service, using NetTcpBinding in a Windows service. 我正在尝试在Windows服务中使用NetTcpBinding承载WCF服务。 (I'm going to use it as an API for various clients both Web and Windows32) Obviously, I am doing this within a test host before putting it in a Windows service. (我将使用它作为Web和Windows32各种客户端的API)显然,在将其放入Windows服务之前,我正在测试主机中进行此操作。

I have the following contract: 我有以下合同:

namespace yyy.xxx.Server.API.WCF
{
    [ServiceContract]
    public interface ISecureSessionBroker
    {
        [OperationContract]
        string GetSessionToken(string username, string encryptedPassword, string clientApiKey, string clientAddress);
    }
}

with the following implementation: 具有以下实现:

namespace yyy.xxx.Server.API.WCF
{
    public class SecureSessionBroker : ISecureSessionBroker
    {
        #region ~ from ISecureSessionBroker ~

        public string GetSessionToken(string username, string encryptedPassword, string clientApiKey, string clientAddress)
        {
            return Guid.NewGuid().ToString();
        }

        #endregion
    }
}

I am hosting the WCF service using the code below (within a class/method): 我正在使用以下代码(在类/方法内)托管WCF服务:

try
{
    _secureSessionBrokerHost = new ServiceHost(typeof(SecureSessionBroker));
    NetTcpBinding netTcpBinding = new NetTcpBinding();
    _secureSessionBrokerHost.AddServiceEndpoint(typeof(ISecureSessionBroker), netTcpBinding, "net.tcp://localhost:8080/secureSessionBrokerTcp");
    int newLimit = _secureSessionBrokerHost.IncrementManualFlowControlLimit(100);
    // Open the ServiceHost to start listening for messages.
    _secureSessionBrokerHost.Open();

}
catch (Exception ex)
{
throw;
}

The key thing here is that I do not want to have to rely on an App.config file. 这里的关键是我不想依赖于App.config文件。 Everything must be configured programmatically. 一切都必须以编程方式进行配置。 When I run this code, the service appears to come "up" and listen. 当我运行此代码时,该服务似乎“启动”并监听。 (ie. I have no exceptions) (即,我也没有例外)

BUT when I use the client code below: 但是当我使用下面的客户端代码时:

string secureSessionBrokerUrl = string.Format("{0}/secureSessionBrokerTcp","net.tcp://localhost/8080",url);
EndpointAddress endpointAddress=new EndpointAddress(secureSessionBrokerUrl);
System.ServiceModel.Channels.Binding binding = new NetTcpBinding();
yyy.xxx.Windows.AdminTool.API.WCF.SecureSessions.SecureSessionBrokerClient
    client = new yyy.xxx.Windows.AdminTool.API.WCF.SecureSessions.SecureSessionBrokerClient(binding,endpointAddress);
string sessionToken=client.GetSessionToken("", "", ""); // exception here
MessageBox.Show(sessionToken);

... I always get an exception. ...我总是例外。 At the moment, I am getting: 此刻,我得到:

This request operation sent to net.tcp://localhost:8080/secureSessionBrokerTcp did not receive a reply within the configured timeout (00:01:00). 发送到net.tcp:// localhost:8080 / secureSessionBrokerTcp的此请求操作在配置的超时(00:01:00)内未收到答复。 The time allotted to this operation may have been a portion of a longer timeout. 分配给该操作的时间可能是较长超时的一部分。 This may be because the service is still processing the operation or because the service was unable to send a reply message. 这可能是因为该服务仍在处理该操作,或者是因为该服务无法发送回复消息。 Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client. 请考虑增加操作超时(通过将通道/代理转换为IContextChannel并设置OperationTimeout属性),并确保该服务能够连接到客户端。

So I guess it cannot resolve the service. 因此,我猜它无法解决该服务。

Where am I going wrong? 我要去哪里错了? How do I test for the existence of the service over TCP? 如何通过TCP测试服务是否存在? I have used the SvcTraceViewer and I just get the same message, so no news there. 我已经使用了SvcTraceViewer,并且只收到相同的消息,所以那里没有新闻。

I would prefer to ask the user for a URL of the service, so they would enter "net.tcp://localhost:8080" or something, which would then be used as a BaseAddress for the various calls to the SecureSessionBroker (and other) WCF services ... without resorting to App.config. 我希望向用户询问服务的URL,因此他们将输入“ net.tcp:// localhost:8080”或其他内容,然后将其用作对SecureSessionBroker(和其他端口)进行各种调用的BaseAddress。 )WCF服务...无需借助App.config。

Unfortunately, all the examples I can find all use the App.config. 不幸的是,我可以找到的所有示例都使用App.config。

Interestingly, I can host the service using the VS Host and the client connects fine. 有趣的是,我可以使用VS Host托管服务,并且客户端连接良好。 (Using: D:\\dev2008\\xxx\\yyy.xxx.Server>WcfSvcHost.exe /service:bin/debug/yyy. xxx.Server.dll /config:App.config) (使用:D:\\ dev2008 \\ xxx \\ yyy.xxx.Server> WcfSvcHost.exe / service:bin / debug / yyy。xxx.Server.dll /config:App.config)

Ok, it came to me in a flash of inspiration. 好的,这是我的灵感。

I was using a Windows Form (alarm bells) to "host" the service. 我正在使用Windows窗体(警报)“托管”服务。 Clicking out of the form, I used a bit of code to call the service (included) on a button click. 单击表单外的按钮,我使用了一些代码来调用该服务(包括)。 Of course, the service was not in its own thread, so the service could not respond. 当然,该服务不在其自己的线程中,因此该服务无法响应。

I've fixed it by putting the Service container (which contains the host) within its own thread: 我已经通过将Service容器(包含主机)放在其自己的线程中来解决此问题:

Thread thread = new Thread(new ThreadStart(_serviceWrapper.Start));
thread.Start();

The Start() method sets up the ServiceHost. Start()方法设置ServiceHost。

I incorrectly thought that while a WCF Service Host will create threads for incoming requests, it will only do this if it is in its own non-blocking thread (ie. not a UI thread). 我错误地认为,虽然WCF服务主机将为传入的请求创建线程,但仅当它位于其自己的非阻塞线程(即,不是UI线程)中时才这样做。

Hope it helps someone else. 希望它可以帮助别人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM