我已按照此示例在ASP.NET网站和C#项目之间创建通信:https://dopeydev.com/wcf-interprocess-communication/
在一段时间不活动后,服务进入故障状态,我不能再交换数据了:
抛出异常:' System.ServiceModel.CommunicationObjectFaultedException'在mscorlib.dll中
当我尝试从网站发送消息时会引发此异常,例如:
service.SendMessage("Hi, I'm the client");
有没有办法让服务永久启用? 它可以在局域网上工作,网页是一个控制界面,每隔几个小时就可以发送一次数据。
这里是服务器配置:
using System.ServiceModel;
using System;
namespace MyProject
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class IServer : Interfaces.IService
{
public void Connect()
{
Callback = OperationContext.Current.GetCallbackChannel<Interfaces.ICallbackService>();
}
public static Interfaces.ICallbackService Callback { get; set; }
public void SendMessage(string message)
{
MessageReceivedEventArgs args = new MessageReceivedEventArgs();
args.json = message;
OnMessageReceived(this, args);
}
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
protected virtual void OnMessageReceived(object sender, MessageReceivedEventArgs e)
{
MessageReceived?.Invoke(this, e);
}
}
public class MessageReceivedEventArgs : EventArgs
{
public string json;
}
}
答案 0 :(得分:1)
由于您的服务具有单个实例,因此可以保持与其的永久连接。永久连接不好,因为它们消耗资源,但如果您真的需要它,那么您需要将receiveTimeout
两侧设置为TimeSpan.Max
。通过这种方式,WCF不会像现在那样关闭连接。
在您的示例代码中,您需要在客户端和服务器代码中将new NetNamedPipeBinding()
替换为new NetNamedPipeBinding() { ReceiveTimeout = TimeSpan.Max }
。
根据服务代码,您不要假设连接的客户端超过1个(因为Callback
是静态字段),但仍然要注意,如果客户端断开连接,那么Callback
看起来有效,但如果你尝试发送它会抛出的东西。
答案 1 :(得分:0)
我最终得到了这段代码。它似乎有效,但我想知道它有多强大。
public bool CheckConnection()
{
if (pipeFactory == null)
{
pipeFactory = new DuplexChannelFactory<IService>(new InstanceContext(_instance), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/ipc"));
}
try
{
switch (pipeFactory.State)
{
case CommunicationState.Faulted:
pipeFactory.Abort();
pipeFactory = new DuplexChannelFactory<IService>(new InstanceContext(_instance), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/ipc"));
service = pipeFactory.CreateChannel();
service.Connect();
break;
case CommunicationState.Closed:
service = pipeFactory.CreateChannel();
service.Connect();
break;
case CommunicationState.Created:
service = pipeFactory.CreateChannel();
service.Connect();
break;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
throw;
}
return pipeFactory.State == CommunicationState.Opened;
}
这不起作用。即使pipeFactory.State
为Opened
,在一段时间不活动后也会引发以下异常:
抛出异常:mscorlib.dll中的“System.ServiceModel.CommunicationObjectFaultedException”
System.ServiceModel.CommunicationObjectFaultedException:通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。
服务器堆栈跟踪: 在System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen() 在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object [] outs,TimeSpan timeout) 在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作) 在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
在[0]处重新抛出异常: 在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData,Int32 type) 在Interfaces.IService.SendMessage(String message) 在_Default.Submit1(String name,String surname,String country,String email,Boolean disclaimer1,Boolean disclaimer2)中的Default.aspx.cs:第99行