我是WCF的新手,我正在努力学习,但我想我在这里遗漏了一些重要的东西而且我知道这一点,所以请善待。我正在使用一个预先存在的控制台应用程序,我已经添加了一个WCF主机,这是它的一个过于简化的版本,但它应该给你它的主旨
namespace mynamespace
{
public class MyConsoleApp
{
static void Main(string[] args)
{
CreateRemoteDebugHost();
StartLongRunningMethods();
}
public static void StartLongRunningMethods()
{
LongRunningMethod1();
LongRunningMethod2();
}
public static void LongRunningMethod1()
{}
public static void LongRunningMethod2()
{}
public void CreateRemoteDebugHost()
{
ServiceHost host = new ServiceHost(typeof(RemoteDebug), new Uri("net.pipe://localhost"));
host.AddServiceEndpoint(typeof(IRemoteDebug), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "PipeRemoteDebug");
//Create mex
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:8001/RemoteDebug");
host.Description.Behaviors.Add(smb);
host.Open();
}
}
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IRemoteDebugCallback))]
public interface IRemoteDebug
{
[OperationContract]
string Message(string message);
}
public interface IRemoteDebugCallback
{
[OperationContract(IsOneWay = true)]
void OnMessage(string callbackValue);
}
public class RemoteDebug : IRemoteDebug
{
public string Message(string message)
{
IRemoteDebugCallback callback = OperationContext.Current.GetCallbackChannel<IRemoteDebugCallback>();
callback.OnMessage(message);
return message;
}
}
}
您可能会告诉我我正在尝试从长时间运行的静态方法中将调试或状态消息发送回客户端。所有的管道似乎工作正常,主机出现,我可以添加一个服务引用到我的客户端应用程序就好但是当尝试从longrunningprocesses静态方法调用WCF回调时,麻烦就开始了。我似乎无法弄清楚如何正确地做到这一点。
同样令人困惑的是,我所看到的WCF和回调几乎所有的例子都假设你所做的一切都是在WCF主机本身的上下文中运行的,显然在我的例子中并非如此。我知道我可能会因为这一切都错了所以有人可以请我直截了当吗?非常感谢任何帮助。
TIA!
答案 0 :(得分:1)
通过app.config或手动创建客户端(不要与客户端程序混淆)(例如public class MyClient: ClientBase<IRemoteDebug>
或public class MyClient: DuplexClientBase<IRemoteDebug>, IRemoteDebug
)。这应该发送消息到客户端程序。上面使用我的一些代码使用DuplexClient的示例:
[CallbackBehaviorAttribute(UseSynchronizationContext = true)]
public class SubCallback : IRemoteDebug
{
public void Event(SomeClass evt)
{
// some handling code using:
//public delegate void EventCallbackHandler(SomeClass evt);
}
}
InstanceContext ctx = new InstanceContext(new SubCallback ());
MyClient _client = new MyClient(
ctx,
new NetNamedPipeBinding(NetNamedPipeSecurityMode.None),
new EndpointAddress("net.pipe://localhost/ServiceEndpointName"));
此外,您可能希望将一些选项传递给您的服务,例如:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
public class RemoteDebug : IRemoteDebug
{}
可能是导致您遇到特定问题的很多因素,但这解决了我的问题。