Why do I get a WCF timeout even though my service call and callback are successful?

Posted by KallDrexx on Stack Overflow See other posts from Stack Overflow or by KallDrexx
Published on 2012-08-01T03:47:48Z Indexed on 2012/10/26 17:02 UTC
Read the original article Hit count: 211

Filed under:
|

I'm playing around with hooking up an in-game console to a WCF interface, so an external application can send console commands and receive console output. To accomplish this I created the following service contracts:

public interface IConsoleNetworkCallbacks
{
    [OperationContract(IsOneWay = true)]
    void NewOutput(IEnumerable<string> text, string category);
}

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IConsoleNetworkCallbacks))]
public interface IConsoleInterface
{
    [OperationContract]
    void ProcessInput(string input);

    [OperationContract]
    void ChangeCategory(string category);
}

On the server I implemented it with:

public class ConsoleNetworkInterface : IConsoleInterface, IDisposable
{
    public ConsoleNetworkInterface()
    {
        ConsoleManager.Instance.RegisterOutputUpdateHandler(OutputHandler);
    }

    public void Dispose()
    {
        ConsoleManager.Instance.UnregisterOutputHandler(OutputHandler);
    }

    public void ProcessInput(string input)
    {
        ConsoleManager.Instance.ProcessInput(input);
    }

    public void ChangeCategory(string category)
    {
        ConsoleManager.Instance.UnregisterOutputHandler(OutputHandler);
        ConsoleManager.Instance.RegisterOutputUpdateHandler(OutputHandler, category);
    }

    protected void OutputHandler(IEnumerable<string> text, string category)
    {
        var callbacks = OperationContext.Current.GetCallbackChannel<IConsoleNetworkCallbacks>();
        callbacks.NewOutput(text, category);
    }
}

On the client I implemented the callback with:

public class Callbacks : IConsoleNetworkCallbacks
{
    public void NewOutput(IEnumerable<string> text, string category)
    {
        MessageBox.Show(string.Format("{0} lines received for '{1}' category", text.Count(), category));
    }
}

Finally, I establish the service host with the following class:

public class ConsoleServiceHost : IDisposable
{
    protected ServiceHost _host;

    public ConsoleServiceHost()
    {
        _host = new ServiceHost(typeof(ConsoleNetworkInterface), new Uri[] { new Uri("net.pipe://localhost") });
        _host.AddServiceEndpoint(typeof(IConsoleInterface), new NetNamedPipeBinding(), "FrbConsolePipe");

        _host.Open();
    }

    public void Dispose()
    {
        _host.Close();
    }
}

and use the following code on my client to establish the connection:

    protected Callbacks _callbacks;
    protected IConsoleInterface _proxy;

    protected void ConnectToConsoleServer()
    {
        _callbacks = new Callbacks();
        var factory = new DuplexChannelFactory<IConsoleInterface>(_callbacks,
            new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/FrbConsolePipe"));
        _proxy = factory.CreateChannel();
        _proxy.ProcessInput("Connected");
    }

So what happens is that my ConnectToConsoleServer() is called and then it gets all the way to _proxy.ProcessInput("Connected");. In my game (on the server) I immediately see the output caused by the ProcessInput call, but the client is still stalled on the _proxy.ProcessInput() call.

After a minute my client gets a JIT TimeoutException however at the same time my MessageBox message appears.

So obviously not only is my command being sent immediately, my callback is being correctly called. So why am I getting a timeout exception?

Note: Even removing the MessageBox call, I still have this issue, so it's not an issue of the GUI blocking the callback response.

© Stack Overflow or respective owner

Related posts about c#

Related posts about wcf