BinaryClientFormatterSink.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. BinaryCore _binaryCore = BinaryCore.DefaultInstance;
  21. IClientChannelSink _nextInChain;
  22. public BinaryClientFormatterSink (IClientChannelSink nextSink)
  23. {
  24. _nextInChain = nextSink;
  25. }
  26. internal BinaryCore BinaryCore
  27. {
  28. get { return _binaryCore; }
  29. set { _binaryCore = value; }
  30. }
  31. public IClientChannelSink NextChannelSink
  32. {
  33. get {
  34. return _nextInChain;
  35. }
  36. }
  37. public IMessageSink NextSink
  38. {
  39. get {
  40. // This is the last sink in the IMessageSink sink chain
  41. return null;
  42. }
  43. }
  44. public IDictionary Properties
  45. {
  46. get {
  47. return null;
  48. }
  49. }
  50. public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
  51. IMessage msg,
  52. ITransportHeaders headers,
  53. Stream stream)
  54. {
  55. // never called because the formatter sink is
  56. // always the first in the chain
  57. throw new NotSupportedException("BinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
  58. }
  59. public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
  60. object state,
  61. ITransportHeaders headers,
  62. Stream stream)
  63. {
  64. IMessage replyMessage = (IMessage)_binaryCore.Deserializer.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state);
  65. sinkStack.DispatchReplyMessage (replyMessage);
  66. }
  67. public Stream GetRequestStream (IMessage msg,
  68. ITransportHeaders headers)
  69. {
  70. // never called
  71. throw new NotSupportedException ();
  72. }
  73. public void ProcessMessage (IMessage msg,
  74. ITransportHeaders requestHeaders,
  75. Stream requestStream,
  76. out ITransportHeaders responseHeaders,
  77. out Stream responseStream)
  78. {
  79. // never called because the formatter sink is
  80. // always the first in the chain
  81. throw new NotSupportedException ();
  82. }
  83. public IMessageCtrl AsyncProcessMessage (IMessage msg,
  84. IMessageSink replySink)
  85. {
  86. ITransportHeaders transportHeaders = new TransportHeaders();
  87. Stream stream = _nextInChain.GetRequestStream(msg, transportHeaders);
  88. if (stream == null) stream = new MemoryStream ();
  89. _binaryCore.Serializer.Serialize (stream, msg, null);
  90. if (stream is MemoryStream) stream.Position = 0;
  91. ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
  92. stack.Push (this, msg);
  93. _nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream);
  94. // FIXME: No idea about how to implement IMessageCtrl
  95. return null;
  96. }
  97. public IMessage SyncProcessMessage (IMessage msg)
  98. {
  99. try {
  100. ITransportHeaders call_headers = new TransportHeaders();
  101. call_headers[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
  102. call_headers["Content-Type"] = "application/octet-stream";
  103. Stream call_stream = _nextInChain.GetRequestStream(msg, call_headers);
  104. if (call_stream == null) call_stream = new MemoryStream ();
  105. // Serialize msg to the stream
  106. _binaryCore.Serializer.Serialize (call_stream, msg, null);
  107. if (call_stream is MemoryStream) call_stream.Position = 0;
  108. Stream response_stream;
  109. ITransportHeaders response_headers;
  110. _nextInChain.ProcessMessage (msg, call_headers, call_stream, out response_headers,
  111. out response_stream);
  112. // Deserialize response_stream
  113. return (IMessage) _binaryCore.Deserializer.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
  114. } catch (Exception e) {
  115. return new ReturnMessage (e, (IMethodCallMessage)msg);
  116. }
  117. }
  118. }
  119. }