|
//*****************************************************************************
// Description.....Null Transport
//
// Author..........Roman Kiss, rkiss@pathcom.com
// Copyright © 2007 ATZ Consulting Inc. (see included license.rtf file)
//
// Date Created: 07/07/07
//
// Date Modified By Description
//-----------------------------------------------------------------------------
// 07/07/07 Roman Kiss Initial Revision
//*****************************************************************************
//
#region Namespaces
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Threading;
#endregion
namespace RKiss.NullChannelLib
{
public class NullReplyChannelListener : ChannelListenerBase<IReplyChannel>, IChannel
{
#region Private members
NullTransportBindingElement _element = null;
BindingContext _context = null;
EndpointAddress _localAddress = null;
EndpointAddressMessageFilter _filter = null;
// only one channel is supported
NullReplyChannel _currentChannel = null;
AutoResetEvent _waitChannel = new AutoResetEvent(false);
#endregion
#region Constructors
public NullReplyChannelListener(NullTransportBindingElement element, BindingContext context)
: base(context.Binding)
{
_element = element;
_context = context;
_localAddress = new EndpointAddress(new Uri(context.ListenUriBaseAddress, context.ListenUriRelativeAddress));
//_localAddress = new EndpointAddress(context.ListenUriBaseAddress);
_filter = new EndpointAddressMessageFilter(_localAddress);
}
#endregion
#region Enqueing
public void EnqueueItem(object item)
{
lock (this.ThisLock)
{
_currentChannel.Dispatch(item as NullAsyncRequestContext);
}
}
#endregion
#region Uri
public override Uri Uri
{
get { return _localAddress.Uri; }
}
#endregion
#region Shutdown
private void Shutdown()
{
lock (this.ThisLock)
{
NullListeners.Current.Remove(_filter);
if (_currentChannel != null)
{
_currentChannel.Abort();
_currentChannel = null;
}
}
_waitChannel.Set();
}
#endregion
#region Abort
protected override void OnAbort()
{
lock (this.ThisLock)
{
if (_currentChannel != null)
{
_currentChannel.Abort();
_currentChannel = null;
}
}
_waitChannel.Set();
}
#endregion
#region Close
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
this.OnClose(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnClose(TimeSpan timeout)
{
this.Shutdown();
}
protected override void OnEndClose(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
internal void OnCurrentChannelClosed(object sender, EventArgs e)
{
lock (ThisLock)
{
if (_currentChannel != null)
{
_currentChannel.Closed -= new EventHandler(OnCurrentChannelClosed);
}
_waitChannel.Set();
}
}
#endregion
#region Open
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
this.OnOpen(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnOpen(TimeSpan timeout)
{
// nothing to do
}
protected override void OnEndOpen(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
#endregion
#region Accept
protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state)
{
this.OnAcceptChannel(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override IReplyChannel OnAcceptChannel(TimeSpan timeout)
{
if (base.State != CommunicationState.Opened)
{
throw new CommunicationObjectFaultedException(string.Format("The channel {0} is not opened", this.GetType().Name));
}
if (_currentChannel != null)
{
// we are supporting only one channel, therefore we have to waiting for next one
_waitChannel.WaitOne(int.MaxValue, true);
lock (ThisLock)
{
// re-open channel
if (base.State == CommunicationState.Opened && _currentChannel != null && _currentChannel.State == CommunicationState.Closed)
{
_currentChannel = new NullReplyChannel(this, _localAddress);
_currentChannel.Closed += new EventHandler(OnCurrentChannelClosed);
}
}
}
else
{
lock (ThisLock)
{
// open channel at first time
_currentChannel = new NullReplyChannel(this, _localAddress);
_currentChannel.Closed += new EventHandler(OnCurrentChannelClosed);
int count = NullListeners.Current.Add(_filter, this);
}
}
return _currentChannel;
}
protected override IReplyChannel OnEndAcceptChannel(IAsyncResult result)
{
CompletedAsyncResult.End(result);
return _currentChannel;
}
#endregion
#region WaitForChannel - NotImplemented
protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
{
throw new NotImplementedException();
}
protected override bool OnEndWaitForChannel(IAsyncResult result)
{
throw new NotImplementedException();
}
protected override bool OnWaitForChannel(TimeSpan timeout)
{
throw new NotImplementedException();
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.