e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
228 lines
8.3 KiB
C#
228 lines
8.3 KiB
C#
//----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//----------------------------------------------------------------------------
|
|
namespace System.ServiceModel.Channels
|
|
{
|
|
using System;
|
|
using System.ServiceModel.Activation;
|
|
using System.ServiceModel;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Collections.Generic;
|
|
|
|
abstract class ConnectionOrientedTransportManager<TChannelListener> : TransportManager
|
|
where TChannelListener : ConnectionOrientedTransportChannelListener
|
|
{
|
|
UriPrefixTable<TChannelListener> addressTable;
|
|
int connectionBufferSize;
|
|
TimeSpan channelInitializationTimeout;
|
|
int maxPendingConnections;
|
|
TimeSpan maxOutputDelay;
|
|
int maxPendingAccepts;
|
|
TimeSpan idleTimeout;
|
|
int maxPooledConnections;
|
|
Action messageReceivedCallback;
|
|
|
|
protected ConnectionOrientedTransportManager()
|
|
{
|
|
this.addressTable = new UriPrefixTable<TChannelListener>();
|
|
}
|
|
|
|
UriPrefixTable<TChannelListener> AddressTable
|
|
{
|
|
get { return addressTable; }
|
|
}
|
|
|
|
protected TimeSpan ChannelInitializationTimeout
|
|
{
|
|
get
|
|
{
|
|
return channelInitializationTimeout;
|
|
}
|
|
}
|
|
|
|
internal void ApplyListenerSettings(IConnectionOrientedListenerSettings listenerSettings)
|
|
{
|
|
this.connectionBufferSize = listenerSettings.ConnectionBufferSize;
|
|
this.channelInitializationTimeout = listenerSettings.ChannelInitializationTimeout;
|
|
this.maxPendingConnections = listenerSettings.MaxPendingConnections;
|
|
this.maxOutputDelay = listenerSettings.MaxOutputDelay;
|
|
this.maxPendingAccepts = listenerSettings.MaxPendingAccepts;
|
|
this.idleTimeout = listenerSettings.IdleTimeout;
|
|
this.maxPooledConnections = listenerSettings.MaxPooledConnections;
|
|
}
|
|
|
|
internal int ConnectionBufferSize
|
|
{
|
|
get
|
|
{
|
|
return this.connectionBufferSize;
|
|
}
|
|
}
|
|
|
|
internal int MaxPendingConnections
|
|
{
|
|
get
|
|
{
|
|
return this.maxPendingConnections;
|
|
}
|
|
}
|
|
|
|
internal TimeSpan MaxOutputDelay
|
|
{
|
|
get
|
|
{
|
|
return maxOutputDelay;
|
|
}
|
|
}
|
|
|
|
internal int MaxPendingAccepts
|
|
{
|
|
get
|
|
{
|
|
return this.maxPendingAccepts;
|
|
}
|
|
}
|
|
|
|
internal TimeSpan IdleTimeout
|
|
{
|
|
get { return this.idleTimeout; }
|
|
}
|
|
|
|
internal int MaxPooledConnections
|
|
{
|
|
get { return this.maxPooledConnections; }
|
|
}
|
|
|
|
internal bool IsCompatible(ConnectionOrientedTransportChannelListener channelListener)
|
|
{
|
|
if (channelListener.InheritBaseAddressSettings)
|
|
return true;
|
|
|
|
return (
|
|
(this.ChannelInitializationTimeout == channelListener.ChannelInitializationTimeout) &&
|
|
(this.ConnectionBufferSize == channelListener.ConnectionBufferSize) &&
|
|
(this.MaxPendingConnections == channelListener.MaxPendingConnections) &&
|
|
(this.MaxOutputDelay == channelListener.MaxOutputDelay) &&
|
|
(this.MaxPendingAccepts == channelListener.MaxPendingAccepts) &&
|
|
(this.idleTimeout == channelListener.IdleTimeout) &&
|
|
(this.maxPooledConnections == channelListener.MaxPooledConnections)
|
|
);
|
|
}
|
|
|
|
TChannelListener GetChannelListener(Uri via)
|
|
{
|
|
TChannelListener channelListener = null;
|
|
if (AddressTable.TryLookupUri(via, HostNameComparisonMode.StrongWildcard, out channelListener))
|
|
{
|
|
return channelListener;
|
|
}
|
|
|
|
if (AddressTable.TryLookupUri(via, HostNameComparisonMode.Exact, out channelListener))
|
|
{
|
|
return channelListener;
|
|
}
|
|
|
|
AddressTable.TryLookupUri(via, HostNameComparisonMode.WeakWildcard, out channelListener);
|
|
return channelListener;
|
|
}
|
|
|
|
internal void OnDemuxerError(Exception exception)
|
|
{
|
|
lock (ThisLock)
|
|
{
|
|
this.Fault(this.AddressTable, exception);
|
|
}
|
|
}
|
|
|
|
internal ISingletonChannelListener OnGetSingletonMessageHandler(ServerSingletonPreambleConnectionReader serverSingletonPreambleReader)
|
|
{
|
|
Uri via = serverSingletonPreambleReader.Via;
|
|
TChannelListener channelListener = GetChannelListener(via);
|
|
|
|
if (channelListener != null)
|
|
{
|
|
if (channelListener is IChannelListener<IReplyChannel>)
|
|
{
|
|
channelListener.RaiseMessageReceived();
|
|
return (ISingletonChannelListener)channelListener;
|
|
}
|
|
else
|
|
{
|
|
serverSingletonPreambleReader.SendFault(FramingEncodingString.UnsupportedModeFault);
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
|
new ProtocolException(SR.GetString(SR.FramingModeNotSupported, FramingMode.Singleton)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
serverSingletonPreambleReader.SendFault(FramingEncodingString.EndpointNotFoundFault);
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
|
new EndpointNotFoundException(SR.GetString(SR.EndpointNotFound, via)));
|
|
}
|
|
}
|
|
|
|
internal void OnHandleServerSessionPreamble(ServerSessionPreambleConnectionReader serverSessionPreambleReader,
|
|
ConnectionDemuxer connectionDemuxer)
|
|
{
|
|
Uri via = serverSessionPreambleReader.Via;
|
|
TChannelListener channelListener = GetChannelListener(via);
|
|
|
|
if (channelListener != null)
|
|
{
|
|
ISessionPreambleHandler sessionPreambleHandler = channelListener as ISessionPreambleHandler;
|
|
|
|
if (sessionPreambleHandler != null && channelListener is IChannelListener<IDuplexSessionChannel>)
|
|
{
|
|
sessionPreambleHandler.HandleServerSessionPreamble(serverSessionPreambleReader, connectionDemuxer);
|
|
}
|
|
else
|
|
{
|
|
serverSessionPreambleReader.SendFault(FramingEncodingString.UnsupportedModeFault);
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
|
new ProtocolException(SR.GetString(SR.FramingModeNotSupported, FramingMode.Duplex)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
serverSessionPreambleReader.SendFault(FramingEncodingString.EndpointNotFoundFault);
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new EndpointNotFoundException(SR.GetString(SR.DuplexSessionListenerNotFound, via.ToString())));
|
|
}
|
|
}
|
|
|
|
internal IConnectionOrientedTransportFactorySettings OnGetTransportFactorySettings(Uri via)
|
|
{
|
|
return GetChannelListener(via);
|
|
}
|
|
|
|
internal override void Register(TransportChannelListener channelListener)
|
|
{
|
|
AddressTable.RegisterUri(channelListener.Uri, channelListener.HostNameComparisonModeInternal,
|
|
(TChannelListener)channelListener);
|
|
|
|
channelListener.SetMessageReceivedCallback(new Action(OnMessageReceived));
|
|
}
|
|
|
|
internal override void Unregister(TransportChannelListener channelListener)
|
|
{
|
|
EnsureRegistered(AddressTable, (TChannelListener)channelListener, channelListener.HostNameComparisonModeInternal);
|
|
AddressTable.UnregisterUri(channelListener.Uri, channelListener.HostNameComparisonModeInternal);
|
|
channelListener.SetMessageReceivedCallback(null);
|
|
}
|
|
|
|
internal void SetMessageReceivedCallback(Action messageReceivedCallback)
|
|
{
|
|
this.messageReceivedCallback = messageReceivedCallback;
|
|
}
|
|
|
|
void OnMessageReceived()
|
|
{
|
|
Action callback = this.messageReceivedCallback;
|
|
if (callback != null)
|
|
{
|
|
callback();
|
|
}
|
|
}
|
|
}
|
|
}
|