BinaryClientFormatterSink.cs 4.3 KB

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