379 lines
14 KiB
C#
379 lines
14 KiB
C#
|
//----------------------------------------------------------------
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.ServiceModel.Channels
|
|||
|
{
|
|||
|
using System;
|
|||
|
using System.Runtime;
|
|||
|
using System.ServiceModel.Routing;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Security.Principal;
|
|||
|
using SR2 = System.ServiceModel.SR;
|
|||
|
|
|||
|
class SynchronousSendBindingElement : BindingElement
|
|||
|
{
|
|||
|
public override BindingElement Clone()
|
|||
|
{
|
|||
|
return new SynchronousSendBindingElement();
|
|||
|
}
|
|||
|
|
|||
|
public override T GetProperty<T>(BindingContext context)
|
|||
|
{
|
|||
|
if (context == null)
|
|||
|
{
|
|||
|
throw FxTrace.Exception.ArgumentNull("context");
|
|||
|
}
|
|||
|
|
|||
|
return context.GetInnerProperty<T>();
|
|||
|
}
|
|||
|
|
|||
|
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
|
|||
|
{
|
|||
|
if (context == null)
|
|||
|
{
|
|||
|
throw FxTrace.Exception.ArgumentNull("context");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
Type typeofTChannel = typeof(TChannel);
|
|||
|
|
|||
|
if (typeofTChannel == typeof(IDuplexChannel) ||
|
|||
|
typeofTChannel == typeof(IDuplexSessionChannel) ||
|
|||
|
typeofTChannel == typeof(IRequestChannel) ||
|
|||
|
typeofTChannel == typeof(IRequestSessionChannel) ||
|
|||
|
typeofTChannel == typeof(IOutputChannel) ||
|
|||
|
typeofTChannel == typeof(IOutputSessionChannel))
|
|||
|
{
|
|||
|
return context.CanBuildInnerChannelFactory<TChannel>();
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
|||
|
{
|
|||
|
if (context == null)
|
|||
|
{
|
|||
|
throw FxTrace.Exception.ArgumentNull("context");
|
|||
|
}
|
|||
|
|
|||
|
if (!this.CanBuildChannelFactory<TChannel>(context.Clone()))
|
|||
|
{
|
|||
|
throw FxTrace.Exception.Argument("TChannel", SR2.GetString(SR2.ChannelTypeNotSupported, typeof(TChannel)));
|
|||
|
}
|
|||
|
|
|||
|
IChannelFactory<TChannel> innerFactory = context.BuildInnerChannelFactory<TChannel>();
|
|||
|
if (innerFactory != null)
|
|||
|
{
|
|||
|
return new SynchronousChannelFactory<TChannel>(context.Binding, innerFactory);
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousChannelFactory<TChannel> : LayeredChannelFactory<TChannel>
|
|||
|
{
|
|||
|
public SynchronousChannelFactory(IDefaultCommunicationTimeouts timeouts, IChannelFactory<TChannel> innerFactory)
|
|||
|
: base(timeouts, innerFactory)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
this.InnerChannelFactory.Open(timeout);
|
|||
|
return new CompletedAsyncResult(callback, state);
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnEndOpen(IAsyncResult result)
|
|||
|
{
|
|||
|
CompletedAsyncResult.End(result);
|
|||
|
}
|
|||
|
|
|||
|
protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
|
|||
|
{
|
|||
|
IChannelFactory<TChannel> factory = (IChannelFactory<TChannel>)this.InnerChannelFactory;
|
|||
|
TChannel channel = factory.CreateChannel(address, via);
|
|||
|
if (channel != null)
|
|||
|
{
|
|||
|
Type channelType = typeof(TChannel);
|
|||
|
if (channelType == typeof(IDuplexSessionChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousDuplexSessionChannel(this, (IDuplexSessionChannel)channel);
|
|||
|
}
|
|||
|
else if (channelType == typeof(IRequestChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousRequestChannel(this, (IRequestChannel)channel);
|
|||
|
}
|
|||
|
else if (channelType == typeof(IRequestSessionChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousRequestSessionChannel(this, (IRequestSessionChannel)channel);
|
|||
|
}
|
|||
|
else if (channelType == typeof(IOutputChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousOutputChannel(this, (IOutputChannel)channel);
|
|||
|
}
|
|||
|
else if (channelType == typeof(IOutputSessionChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousOutputSessionChannel(this, (IOutputSessionChannel)channel);
|
|||
|
}
|
|||
|
else if (channelType == typeof(IDuplexChannel))
|
|||
|
{
|
|||
|
channel = (TChannel)(object)new SynchronousDuplexChannel(this, (IDuplexChannel)channel);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw FxTrace.Exception.AsError(base.CreateChannelTypeNotSupportedException(typeof(TChannel)));
|
|||
|
}
|
|||
|
}
|
|||
|
return channel;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
abstract class SynchronousChannelBase<TChannel> : LayeredChannel<TChannel>
|
|||
|
where TChannel : class, IChannel
|
|||
|
{
|
|||
|
protected SynchronousChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
this.InnerChannel.Open(timeout);
|
|||
|
return new CompletedAsyncResult(callback, state);
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnEndOpen(IAsyncResult result)
|
|||
|
{
|
|||
|
CompletedAsyncResult.End(result);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousDuplexChannelBase<TChannel> : SynchronousOutputChannelBase<TChannel>
|
|||
|
where TChannel : class, IDuplexChannel
|
|||
|
{
|
|||
|
public SynchronousDuplexChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
return this.InnerChannel.BeginReceive(timeout, callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginReceive(AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
return this.InnerChannel.BeginReceive(callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
return this.InnerChannel.BeginTryReceive(timeout, callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
return this.InnerChannel.BeginWaitForMessage(timeout, callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public Message EndReceive(IAsyncResult result)
|
|||
|
{
|
|||
|
return this.InnerChannel.EndReceive(result);
|
|||
|
}
|
|||
|
|
|||
|
public bool EndTryReceive(IAsyncResult result, out Message message)
|
|||
|
{
|
|||
|
return this.InnerChannel.EndTryReceive(result, out message);
|
|||
|
}
|
|||
|
|
|||
|
public bool EndWaitForMessage(IAsyncResult result)
|
|||
|
{
|
|||
|
return this.InnerChannel.EndWaitForMessage(result);
|
|||
|
}
|
|||
|
|
|||
|
public EndpointAddress LocalAddress
|
|||
|
{
|
|||
|
get { return this.InnerChannel.LocalAddress; }
|
|||
|
}
|
|||
|
|
|||
|
public Message Receive(TimeSpan timeout)
|
|||
|
{
|
|||
|
return this.InnerChannel.Receive(timeout);
|
|||
|
}
|
|||
|
|
|||
|
public Message Receive()
|
|||
|
{
|
|||
|
return this.InnerChannel.Receive();
|
|||
|
}
|
|||
|
|
|||
|
public bool TryReceive(TimeSpan timeout, out Message message)
|
|||
|
{
|
|||
|
return this.InnerChannel.TryReceive(timeout, out message);
|
|||
|
}
|
|||
|
|
|||
|
public bool WaitForMessage(TimeSpan timeout)
|
|||
|
{
|
|||
|
return this.InnerChannel.WaitForMessage(timeout);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousDuplexChannel : SynchronousDuplexChannelBase<IDuplexChannel>, IDuplexChannel
|
|||
|
{
|
|||
|
public SynchronousDuplexChannel(ChannelManagerBase manager, IDuplexChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousDuplexSessionChannel : SynchronousDuplexChannelBase<IDuplexSessionChannel>, IDuplexSessionChannel
|
|||
|
{
|
|||
|
public SynchronousDuplexSessionChannel(ChannelManagerBase manager, IDuplexSessionChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
IDuplexSession ISessionChannel<IDuplexSession>.Session
|
|||
|
{
|
|||
|
get { return this.InnerChannel.Session; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
abstract class SynchronousOutputChannelBase<TChannel> : SynchronousChannelBase<TChannel>
|
|||
|
where TChannel : class, IOutputChannel
|
|||
|
{
|
|||
|
public SynchronousOutputChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
this.InnerChannel.Send(message, timeout);
|
|||
|
return new CompletedAsyncResult(callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
this.InnerChannel.Send(message);
|
|||
|
return new CompletedAsyncResult(callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public void EndSend(IAsyncResult result)
|
|||
|
{
|
|||
|
CompletedAsyncResult.End(result);
|
|||
|
}
|
|||
|
|
|||
|
public EndpointAddress RemoteAddress
|
|||
|
{
|
|||
|
get { return this.InnerChannel.RemoteAddress; }
|
|||
|
}
|
|||
|
|
|||
|
public void Send(Message message, TimeSpan timeout)
|
|||
|
{
|
|||
|
this.InnerChannel.Send(message, timeout);
|
|||
|
}
|
|||
|
|
|||
|
public void Send(Message message)
|
|||
|
{
|
|||
|
this.InnerChannel.Send(message);
|
|||
|
}
|
|||
|
|
|||
|
public Uri Via
|
|||
|
{
|
|||
|
get { return this.InnerChannel.Via; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousOutputChannel : SynchronousOutputChannelBase<IOutputChannel>, IOutputChannel
|
|||
|
{
|
|||
|
public SynchronousOutputChannel(ChannelManagerBase manager, IOutputChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousOutputSessionChannel : SynchronousOutputChannelBase<IOutputSessionChannel>, IOutputSessionChannel
|
|||
|
{
|
|||
|
public SynchronousOutputSessionChannel(ChannelManagerBase manager, IOutputSessionChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
IOutputSession ISessionChannel<IOutputSession>.Session
|
|||
|
{
|
|||
|
get { return this.InnerChannel.Session; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
abstract class SynchronousRequestChannelBase<TChannel> : SynchronousChannelBase<TChannel>
|
|||
|
where TChannel : class, IRequestChannel
|
|||
|
{
|
|||
|
public SynchronousRequestChannelBase(ChannelManagerBase manager, TChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
Message reply = this.InnerChannel.Request(message, timeout);
|
|||
|
return new CompletedAsyncResult<Message>(reply, callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
|
|||
|
{
|
|||
|
Message reply = this.InnerChannel.Request(message);
|
|||
|
return new CompletedAsyncResult<Message>(reply, callback, state);
|
|||
|
}
|
|||
|
|
|||
|
public Message EndRequest(IAsyncResult result)
|
|||
|
{
|
|||
|
return CompletedAsyncResult<Message>.End(result);
|
|||
|
}
|
|||
|
|
|||
|
public EndpointAddress RemoteAddress
|
|||
|
{
|
|||
|
get { return this.InnerChannel.RemoteAddress; }
|
|||
|
}
|
|||
|
|
|||
|
public Message Request(Message message, TimeSpan timeout)
|
|||
|
{
|
|||
|
return this.InnerChannel.Request(message, timeout);
|
|||
|
}
|
|||
|
|
|||
|
public Message Request(Message message)
|
|||
|
{
|
|||
|
return this.InnerChannel.Request(message);
|
|||
|
}
|
|||
|
|
|||
|
public Uri Via
|
|||
|
{
|
|||
|
get { return this.InnerChannel.Via; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousRequestChannel : SynchronousRequestChannelBase<IRequestChannel>, IRequestChannel
|
|||
|
{
|
|||
|
public SynchronousRequestChannel(ChannelManagerBase manager, IRequestChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class SynchronousRequestSessionChannel : SynchronousRequestChannelBase<IRequestSessionChannel>, IRequestSessionChannel
|
|||
|
{
|
|||
|
public SynchronousRequestSessionChannel(ChannelManagerBase manager, IRequestSessionChannel innerChannel)
|
|||
|
: base(manager, innerChannel)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public IOutputSession Session
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.InnerChannel.Session;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|