我正在尝试将游戏内控制台连接到 WCF 接口,因此外部应用程序可以发送控制台命令并接收控制台输出。为此,我创建了以下服务合同:
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);
}
在服务器上,我使用以下方法实现了它:
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);
}
}
在客户端上,我使用以下方法实现了回调:
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));
}
}
最后,我使用以下类建立服务主机:
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();
}
}
并在我的客户端上使用以下代码建立连接:
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");
}
所以发生的事情是 myConnectToConsoleServer()
被调用,然后它一直到_proxy.ProcessInput("Connected");
. 在我的游戏中(在服务器上),我立即看到由ProcessInput
调用引起的输出,但客户端仍然停止_proxy.ProcessInput()
调用。
一分钟后,我的客户收到了 JIT ,TimeoutException
但同时出现了我的 MessageBox 消息。
所以显然不仅我的命令被立即发送,我的回调也被正确调用。那么为什么我会收到超时异常?
注意:即使删除 MessageBox 调用,我仍然有这个问题,所以这不是 GUI 阻止回调响应的问题。