1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
//
// System.Runtime.Remoting.Channels.BinaryClientFormatterSink.cs
//
// Author: Rodrigo Moya (rodrigo@ximian.com)
// Dietmar Maurer (dietmar@ximian.com)
// Lluis Sanchez Gual (lluis@ideary.com)
//
// 2002 (C) Copyright, Ximian, Inc.
//
using System.Collections;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace System.Runtime.Remoting.Channels
{
public class BinaryClientFormatterSink : IClientFormatterSink,
IMessageSink, IClientChannelSink, IChannelSinkBase
{
static BinaryFormatter _serializationFormatter;
static BinaryFormatter _deserializationFormatter;
IClientChannelSink nextInChain;
static BinaryClientFormatterSink ()
{
RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector ();
StreamingContext context = new StreamingContext(StreamingContextStates.Remoting, null);
_serializationFormatter = new BinaryFormatter (surrogateSelector, context);
_deserializationFormatter = new BinaryFormatter (null, context);
}
public BinaryClientFormatterSink (IClientChannelSink nextSink)
{
nextInChain = nextSink;
}
public IClientChannelSink NextChannelSink
{
get {
return nextInChain;
}
}
public IMessageSink NextSink
{
get {
// This is the last sink in the IMessageSink sink chain
return null;
}
}
public IDictionary Properties
{
get {
return null;
}
}
public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
IMessage msg,
ITransportHeaders headers,
Stream stream)
{
// never called because the formatter sink is
// always the first in the chain
throw new NotSupportedException("BinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
}
public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
object state,
ITransportHeaders headers,
Stream stream)
{
IMessage replyMessage = (IMessage)_deserializationFormatter.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state);
sinkStack.DispatchReplyMessage (replyMessage);
}
public Stream GetRequestStream (IMessage msg,
ITransportHeaders headers)
{
// never called
throw new NotSupportedException ();
}
public void ProcessMessage (IMessage msg,
ITransportHeaders requestHeaders,
Stream requestStream,
out ITransportHeaders responseHeaders,
out Stream responseStream)
{
// never called because the formatter sink is
// always the first in the chain
throw new NotSupportedException ();
}
public IMessageCtrl AsyncProcessMessage (IMessage msg,
IMessageSink replySink)
{
ITransportHeaders transportHeaders = new TransportHeaders();
transportHeaders[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
Stream stream = nextInChain.GetRequestStream(msg, transportHeaders);
if (stream == null) stream = new MemoryStream ();
_serializationFormatter.Serialize (stream, msg, null);
if (stream is MemoryStream) stream.Position = 0;
ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
stack.Push (this, msg);
nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream);
// FIXME: No idea about how to implement IMessageCtrl
return null;
}
public IMessage SyncProcessMessage (IMessage msg)
{
try {
ITransportHeaders call_headers = new TransportHeaders();
call_headers[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
call_headers["Content-Type"] = "application/octet-stream";
Stream call_stream = nextInChain.GetRequestStream(msg, call_headers);
if (call_stream == null) call_stream = new MemoryStream ();
// Serialize msg to the stream
_serializationFormatter.Serialize (call_stream, msg, null);
if (call_stream is MemoryStream) call_stream.Position = 0;
Stream response_stream;
ITransportHeaders response_headers;
nextInChain.ProcessMessage (msg, call_headers, call_stream, out response_headers,
out response_stream);
// Deserialize response_stream
return (IMessage) _deserializationFormatter.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
} catch (Exception e) {
return new ReturnMessage (e, (IMethodCallMessage)msg);
}
}
}
}
|