5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2009 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System
.Collections
.Generic
;
32 using System
.Net
.Sockets
;
33 using System
.ServiceModel
;
35 using System
.Threading
;
37 namespace System
.ServiceModel
.Channels
39 internal class TcpReplyChannel
: InternalReplyChannelBase
43 TcpBinaryFrameManager frame
;
45 public TcpReplyChannel (ChannelListenerBase listener
, TcpChannelInfo info
, TcpClient client
)
52 public MessageEncoder Encoder
{
53 get { return info.MessageEncoder; }
56 public override RequestContext
ReceiveRequest (TimeSpan timeout
)
58 if (timeout
<= TimeSpan
.Zero
)
59 throw new ArgumentException (String
.Format ("Timeout value must be positive value. It was {0}", timeout
));
61 DateTime start
= DateTime
.Now
;
65 client
= ((TcpChannelListener
<IReplyChannel
>) Manager
).AcceptTcpClient (timeout
);
66 NetworkStream ns
= client
.GetStream ();
67 frame
= new TcpBinaryFrameManager (TcpBinaryFrameManager
.SingletonUnsizedMode
, ns
, true) { Encoder = this.Encoder, EncodingRecord = TcpBinaryFrameManager.EncodingBinary }
;
70 if (!frame
.ProcessPreambleRecipient ())
72 frame
.ProcessPreambleAckRecipient ();
74 var msg
= frame
.ReadUnsizedMessage (timeout
);
75 // LAMESPEC: it contradicts the protocol explanation at section 3.1.1.1.1 in [MC-NMF].
76 // Moving ReadEndRecord() after context's WriteUnsizedMessage() causes TCP connection blocking.
77 frame
.ReadEndRecord ();
78 return new TcpRequestContext (this, msg
);
81 class TcpRequestContext
: InternalRequestContext
83 public TcpRequestContext (TcpReplyChannel owner
, Message request
)
84 : base (owner
.Manager
)
87 this.request
= request
;
90 TcpReplyChannel owner
;
93 public override Message RequestMessage
{
94 get { return request; }
97 public override void Abort ()
99 Close (TimeSpan
.Zero
);
102 public override void Close (TimeSpan timeout
)
106 public override void Reply (Message message
, TimeSpan timeout
)
108 DateTime start
= DateTime
.Now
;
109 owner
.frame
.WriteUnsizedMessage (message
, timeout
);
110 // FIXME: consider timeout here too.
111 owner
.frame
.WriteEndRecord ();
115 public override bool TryReceiveRequest (TimeSpan timeout
, out RequestContext context
)
118 DateTime start
= DateTime
.Now
;
119 context
= ReceiveRequest (timeout
);
120 return context
!= null;
121 } catch (Exception ex
) {
123 // Console.WriteLine (ex);
129 public override bool WaitForRequest (TimeSpan timeout
)
131 throw new NotImplementedException ();
134 protected override void OnClose (TimeSpan timeout
)
138 base.OnClose (timeout
);
141 protected override void OnOpen (TimeSpan timeout
)