213 lines
7.2 KiB
C#
213 lines
7.2 KiB
C#
|
//----------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//----------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Discovery
|
||
|
{
|
||
|
using System;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.Runtime;
|
||
|
using System.ServiceModel.Dispatcher;
|
||
|
using System.Globalization;
|
||
|
|
||
|
sealed class OfflineAnnouncementChannelDispatcher : ChannelDispatcherBase
|
||
|
{
|
||
|
ServiceHostBase serviceHostBase;
|
||
|
IChannelListener closeListener;
|
||
|
|
||
|
internal OfflineAnnouncementChannelDispatcher(ServiceHostBase serviceHostBase, Collection<AnnouncementEndpoint> announcementEndpoints, Collection<EndpointDiscoveryMetadata> publishedEndpoints, DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator)
|
||
|
{
|
||
|
Fx.Assert(serviceHostBase != null, "The serviceHostBase must be non null.");
|
||
|
|
||
|
this.serviceHostBase = serviceHostBase;
|
||
|
this.closeListener = new CloseListener(announcementEndpoints, publishedEndpoints, discoveryMessageSequenceGenerator);
|
||
|
}
|
||
|
|
||
|
public override ServiceHostBase Host
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.serviceHostBase;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IChannelListener Listener
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.closeListener;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override TimeSpan DefaultCloseTimeout
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return TimeSpan.FromMinutes(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override TimeSpan DefaultOpenTimeout
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return TimeSpan.FromMinutes(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnAbort()
|
||
|
{
|
||
|
this.closeListener.Abort();
|
||
|
}
|
||
|
|
||
|
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
|
||
|
{
|
||
|
return this.closeListener.BeginClose(timeout, callback, state);
|
||
|
}
|
||
|
|
||
|
protected override void OnEndClose(IAsyncResult result)
|
||
|
{
|
||
|
this.closeListener.EndClose(result);
|
||
|
}
|
||
|
|
||
|
protected override void OnClose(TimeSpan timeout)
|
||
|
{
|
||
|
this.closeListener.Close(timeout);
|
||
|
}
|
||
|
|
||
|
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
||
|
{
|
||
|
return this.closeListener.BeginOpen(timeout, callback, state);
|
||
|
}
|
||
|
|
||
|
protected override void OnEndOpen(IAsyncResult result)
|
||
|
{
|
||
|
this.closeListener.EndOpen(result);
|
||
|
}
|
||
|
|
||
|
protected override void OnOpen(TimeSpan timeout)
|
||
|
{
|
||
|
this.closeListener.Open(timeout);
|
||
|
}
|
||
|
|
||
|
class CloseListener : CommunicationObject, IChannelListener
|
||
|
{
|
||
|
Collection<AnnouncementEndpoint> announcementEndpoints;
|
||
|
Collection<EndpointDiscoveryMetadata> publishedEndpoints;
|
||
|
AnnouncementDispatcherAsyncResult announceOfflineAsyncResult;
|
||
|
DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator;
|
||
|
bool abortAnnouncement;
|
||
|
|
||
|
public CloseListener(Collection<AnnouncementEndpoint> announcementEndpoints, Collection<EndpointDiscoveryMetadata> publishedEndpoints, DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator)
|
||
|
{
|
||
|
Fx.Assert(announcementEndpoints != null && announcementEndpoints.Count > 0, "The Announcement Endpoints collection must be non null and not empty.");
|
||
|
Fx.Assert(publishedEndpoints != null, "The Published Endpoints collection must be non null.");
|
||
|
Fx.Assert(discoveryMessageSequenceGenerator != null, "The discoveryMessageSequenceGenerator must be non null.");
|
||
|
|
||
|
this.announcementEndpoints = announcementEndpoints;
|
||
|
this.publishedEndpoints = publishedEndpoints;
|
||
|
this.discoveryMessageSequenceGenerator = discoveryMessageSequenceGenerator;
|
||
|
this.abortAnnouncement = false;
|
||
|
}
|
||
|
|
||
|
public Uri Uri
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return new Uri(ProtocolStrings.VersionInternal.AdhocAddress);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override TimeSpan DefaultCloseTimeout
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return TimeSpan.FromMinutes(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override TimeSpan DefaultOpenTimeout
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return TimeSpan.FromMinutes(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnAbort()
|
||
|
{
|
||
|
this.abortAnnouncement = true;
|
||
|
if (this.announceOfflineAsyncResult != null)
|
||
|
{
|
||
|
this.announceOfflineAsyncResult.Cancel();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnClose(TimeSpan timeout)
|
||
|
{
|
||
|
OnEndClose(OnBeginClose(timeout, null, null));
|
||
|
}
|
||
|
|
||
|
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
|
||
|
{
|
||
|
this.announceOfflineAsyncResult = new AnnouncementDispatcherAsyncResult(this.announcementEndpoints, this.publishedEndpoints, this.discoveryMessageSequenceGenerator, false, callback, state);
|
||
|
if (this.abortAnnouncement)
|
||
|
{
|
||
|
// Fixes the ---- when OnAbort is called after OnBeginClose but before this.announceOnlineAsyncResult is created
|
||
|
this.announceOfflineAsyncResult.Cancel();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.announceOfflineAsyncResult.Start(timeout, true);
|
||
|
}
|
||
|
return this.announceOfflineAsyncResult;
|
||
|
}
|
||
|
|
||
|
protected override void OnEndClose(IAsyncResult result)
|
||
|
{
|
||
|
AnnouncementDispatcherAsyncResult.End(result);
|
||
|
}
|
||
|
|
||
|
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
||
|
{
|
||
|
return new CompletedAsyncResult(callback, state);
|
||
|
}
|
||
|
|
||
|
protected override void OnEndOpen(IAsyncResult result)
|
||
|
{
|
||
|
CompletedAsyncResult.End(result);
|
||
|
}
|
||
|
|
||
|
protected override void OnOpen(TimeSpan timeout)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public IAsyncResult BeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
|
||
|
{
|
||
|
return new CompletedAsyncResult<bool>(true, callback, state);
|
||
|
}
|
||
|
|
||
|
public bool EndWaitForChannel(IAsyncResult result)
|
||
|
{
|
||
|
return CompletedAsyncResult<bool>.End(result);
|
||
|
}
|
||
|
|
||
|
public virtual T GetProperty<T>()
|
||
|
where T : class
|
||
|
{
|
||
|
if (typeof(T) == typeof(IChannelListener))
|
||
|
{
|
||
|
return (T)(object)this;
|
||
|
}
|
||
|
|
||
|
return default(T);
|
||
|
}
|
||
|
|
||
|
public bool WaitForChannel(TimeSpan timeout)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|