1 日あたり 70 ~ 80 の接続を処理する WCF パブリッシャー サブスクライバー サービスを作成しました (インターネット接続の障害、システムのシャットダウンなどにより) 接続が途切れた場合、サービス自体は、接続が再開したときに接続自体をセットアップしようとします。
しばらく前に、サービスが例外をスローしていることに気付きました (操作がタイムアウトしました)。
This request operation sent to net.tcp://localhost:2001/sub did not receive a reply within the configured timeout (00:00:59.9799877). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client
そして、これらの例外のいくつかの後、RM宛先タイムアウト例外が発生し、サービスとのさらなる通信のために回線に障害が発生します
信頼できるセッションを作成する要求が、RM 宛先によって拒否されました。サーバー 'net.tcp://localhost:2001/Sub' はビジー状態のため、この要求を処理できません。あとでもう一度試してみてください。チャネルを開くことができませんでした。
この間、すでにサブスクライブしているクライアントは、pub サブ要求に正常に応答しています。
サービスに加入している新しいチャンネルはありません
サービスでネット Tcp バインディングを使用しています
クライアントコード
public class Subscriber : IPublishing
{
static int Counter = 0;
ISubscription _proxy;
string _endpoint = string.Empty;
public Subscriber()
{
_endpoint = "net.tcp://localhost:2001/sub";
MakeProxy(_endpoint, this);
}
void MakeProxy(string EndpoindAddress, object callbackinstance)
{
try
{
NetTcpBinding netTcpbinding = new NetTcpBinding(SecurityMode.None);
EndpointAddress endpointAddress = new EndpointAddress(EndpoindAddress);
InstanceContext context = new InstanceContext(callbackinstance);
// Added for Reliable communication
netTcpbinding.ReliableSession.Enabled = true;
netTcpbinding.ReliableSession.Ordered = true;
netTcpbinding.MaxBufferSize = 2147483647;
netTcpbinding.MaxBufferPoolSize = 2147483647;
netTcpbinding.MaxReceivedMessageSize = 2147483647;
netTcpbinding.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
netTcpbinding.ReceiveTimeout = TimeSpan.MaxValue;
DuplexChannelFactory<ISubscription> channelFactory = new DuplexChannelFactory<ISubscription>(new InstanceContext(this), netTcpbinding, endpointAddress);
_proxy = channelFactory.CreateChannel();
Counter++;
}
catch (Exception ex)
{
//
}
}
public void Subscribe()
{
try
{
_proxy.Subscribe("500");
Counter = 0;
}
catch (Exception ex)
{
((IContextChannel)_proxy).Abort();
}
}
public void Publish(Message e, String ID)
{
}
public void _Subscribe()
{
try
{
//OnUnSubscribe();
Subscribe();
}
catch (Exception ex)
{
}
}
}
サーバーコード
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class Subscription : ISubscription
{
#region ISubscription Members
public void Subscribe(string ID)
{
String s = DateTime.Now.ToString(
IPublishing subscriber = OperationContext.Current.GetCallbackChannel<IPublishing>();
Filter.AddSubscriber(KioskID, subscriber);
}
public void UnSubscribe(string ID)
{
IPublishing subscriber = OperationContext.Current.GetCallbackChannel<IPublishing>();
Filter.RemoveSubscriber(KioskID, subscriber);
}
#endregion
}
class Filter
{
static Dictionary<string, List<IPublishing>> _subscribersList = new Dictionary<string, List<IPublishing>>();
static public Dictionary<string, List<IPublishing>> SubscribersList
{
get
{
lock (typeof(Filter))
{
return _subscribersList;
}
}
}
static public List<IPublishing> GetSubscribers(String topicName)
{
lock (typeof(Filter))
{
if (SubscribersList.ContainsKey(topicName))
{
return SubscribersList[topicName];
}
else
return null;
}
}
static public void AddSubscriber(String topicName, IPublishing subscriberCallbackReference)
{
DebugLog.WriteLog("C:\\DevPubSubServiceLogs", topicName + "came for Sub");
lock (typeof(Filter))
{
DebugLog.WriteLog("C:\\DevPubSubServiceLogs",topicName + "inside lock");
if (SubscribersList.ContainsKey(topicName))
{
// Removing any stray subscribers for same topic name
// because only 1 subscriber for 1 topic name should exist
SubscribersList.Remove(topicName);
}
List<IPublishing> newSubscribersList = new List<IPublishing>();
newSubscribersList.Add(subscriberCallbackReference);
SubscribersList.Add(topicName, newSubscribersList);
}
DebugLog.WriteLog("C:\\DevPubSubServiceLogs", topicName + "subscribed");
}
static public void RemoveSubscriber(String topicName, IPublishing subscriberCallbackReference)
{
lock (typeof(Filter))
{
if (SubscribersList.ContainsKey(topicName))
{
//if (SubscribersList[topicName].Contains(subscriberCallbackReference))
//{
// SubscribersList[topicName].Remove(subscriberCallbackReference);
//}
SubscribersList.Remove(topicName);
}
}
}
}
契約
[ServiceContract]
public interface IPublishing
{
[OperationContract(IsOneWay = true)]
void Publish(Message e, string ID);
}
[ServiceContract(CallbackContract = typeof(IPublishing))]
public interface ISubscription
{
[OperationContract]
void Subscribe(string topicName);
[OperationContract]
void UnSubscribe(string topicName);
}
手伝ってください..