为什么即使我的服务调用和回调成功,我也会收到 WCF 超时? [英] Why do I get a WCF timeout even though my service call and callback are successful?

查看:21
本文介绍了为什么即使我的服务调用和回调成功,我也会收到 WCF 超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将游戏内控制台连接到 WCF 接口,以便外部应用程序可以发送控制台命令并接收控制台输出.为此,我创建了以下服务合同:

公共接口IConsoleNetworkCallbacks{[操作合同(IsOneWay = true)]void NewOutput(IEnumerable text, string category);}[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IConsoleNetworkCallbacks))]公共接口 IConsoleInterface{【经营合同】无效过程输入(字符串输入);【经营合同】无效更改类别(字符串类别);}

在我实现的服务器上:

公共类 ConsoleNetworkInterface : IConsoleInterface, IDisposable{公共控制台网络接口(){ConsoleManager.Instance.RegisterOutputUpdateHandler(OutputHandler);}公共无效处置(){ConsoleManager.Instance.UnregisterOutputHandler(OutputHandler);}public void ProcessInput(字符串输入){ConsoleManager.Instance.ProcessInput(input);}public void ChangeCategory(字符串类别){ConsoleManager.Instance.UnregisterOutputHandler(OutputHandler);ConsoleManager.Instance.RegisterOutputUpdateHandler(OutputHandler, category);}protected void OutputHandler(IEnumerable text, string category){var callbacks = OperationContext.Current.GetCallbackChannel();callbacks.NewOutput(text, category);}}

在客户端上我实现了回调:

公共类回调:IConsoleNetworkCallbacks{public void NewOutput(IEnumerable text, string category){MessageBox.Show(string.Format("{0} 行收到'{1}'类别", text.Count(), category));}}

最后,我使用以下类建立服务主机:

公共类 ConsoleServiceHost : IDisposable{受保护的 ServiceHost _host;公共 ConsoleServiceHost(){_host = new ServiceHost(typeof(ConsoleNetworkInterface), new Uri[] { new Uri("net.pipe://localhost") });_host.AddServiceEndpoint(typeof(IConsoleInterface), new NetNamedPipeBinding(), "FrbConsolePipe");_host.Open();}公共无效处置(){_host.Close();}}

并在我的客户端上使用以下代码建立连接:

 protected Callbacks _callbacks;受保护的 IConsoleInterface _proxy;protected void ConnectToConsoleServer(){_callbacks = new Callbacks();var factory = new DuplexChannelFactory(_callbacks,new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/FrbConsolePipe"));_proxy = factory.CreateChannel();_proxy.ProcessInput("已连接");}

所以会发生什么是我的 ConnectToConsoleServer() 被调用,然后它一直到 _proxy.ProcessInput("Connected");.在我的游戏中(在服务器上),我立即看到了由 ProcessInput 调用引起的输出,但客户端仍然停留在 _proxy.ProcessInput() 调用上.>

一分钟后,我的客户收到 JIT TimeoutException 然而,同时我的 MessageBox 消息出现.

很明显,不仅我的命令被立即发送,我的回调也被正确调用.那么为什么我会收到超时异常?

注意:即使删除了 MessageBox 调用,我仍然有这个问题,所以这不是 GUI 阻止回调响应的问题.

解决方案

可能是你的 _proxy.ProcessInput("Connected") 阻塞了调用 - 这与你的超时体验一致,因为服务器立即发送响应,但客户端无法接收它,因为它卡在ProcessInput"上.当您的调用最终超时时,阻塞调用终止,此时回调完成.

要验证这一点,您可以尝试使用此(非阻塞)调用来代替吗?

((Action)(() => _proxy.ProcessInput("Connected"))).BeginInvoke(null, null);

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.

解决方案

It's possible that it's your _proxy.ProcessInput("Connected") which is blocking the call - this is consistent with your timeout experience, as the server sends the response immediately, but the client can't receive it as it's stuck on "ProcessInput". When your call finally times out, the blocking call terminates, at which point the callback completes.

To verify this, could you try invoking using this (non blocking) call instead?

((Action)(() => _proxy.ProcessInput("Connected"))).BeginInvoke(null, null);

这篇关于为什么即使我的服务调用和回调成功,我也会收到 WCF 超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆