IMessageSink Interfaz

Definición

Define la interfaz de un receptor de mensajes.

public interface class IMessageSink
public interface IMessageSink
[System.Runtime.InteropServices.ComVisible(true)]
public interface IMessageSink
type IMessageSink = interface
[<System.Runtime.InteropServices.ComVisible(true)>]
type IMessageSink = interface
Public Interface IMessageSink
Derivado
Atributos

Ejemplos

En el ejemplo de código siguiente se muestra la implementación de la IMessageSink interfaz . Tenga en cuenta que en el ejemplo se presuponen definiciones de tipos y referencias de ensamblado que se deben proporcionar para que se compile el ejemplo.

#using <System.Runtime.Remoting.dll>
#using <System.dll>
#using <IMessageSink_Share.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Threading;
using namespace System::Runtime::Remoting;
using namespace System::Runtime::Remoting::Channels;
using namespace System::Runtime::Remoting::Channels::Http;
using namespace System::Runtime::Remoting::Proxies;
using namespace System::Runtime::Remoting::Messaging;
using namespace System::Security::Permissions;
using namespace Share;

public ref class MyProxy: public RealProxy
{
private:
   String^ myUrl;
   String^ myObjectURI;
   IMessageSink^ myMessageSink;

public:
    [System::Security::Permissions::PermissionSetAttribute(System::Security::Permissions::SecurityAction::LinkDemand)]

   MyProxy( Type^ myType, String^ myUrl1 )
      : RealProxy( myType )
   {
      myUrl = myUrl1;
      array<IChannel^>^myRegisteredChannels = ChannelServices::RegisteredChannels;
      IEnumerator^ myEnum = myRegisteredChannels->GetEnumerator();
      while ( myEnum->MoveNext() )
      {
         IChannel^ channel = safe_cast<IChannel^>(myEnum->Current);
         if ( dynamic_cast<IChannelSender^>(channel) )
         {
            IChannelSender^ myChannelSender = dynamic_cast<IChannelSender^>(channel);
            myMessageSink = myChannelSender->CreateMessageSink( myUrl, nullptr, myObjectURI );
            if ( myMessageSink != nullptr )
                        break;
         }
      }

      if ( myMessageSink == nullptr )
      {
         throw gcnew Exception( String::Format( "A supported channel could not be found for myUrl1:{0}", myUrl ) );
      }
   }

   virtual IMessage^ Invoke( IMessage^ myMesg ) override
   {
      Console::WriteLine( "MyProxy.Invoke Start" );
      if ( dynamic_cast<IMethodCallMessage^>(myMesg) )
            Console::WriteLine( "IMethodCallMessage" );

      if ( dynamic_cast<IMethodReturnMessage^>(myMesg) )
            Console::WriteLine( "IMethodReturnMessage" );

      
      Console::WriteLine( "Message Properties" );
      IDictionary^ myDictionary = myMesg->Properties;
      IDictionaryEnumerator^ myEnum = dynamic_cast<IDictionaryEnumerator^>(myDictionary->GetEnumerator());
      while ( myEnum->MoveNext() )
      {
         Object^ myKey = myEnum->Key;
         String^ myKeyName = myKey->ToString();
         Object^ myValue = myEnum->Value;
         Console::WriteLine( "{0} : {1}", myKeyName, myEnum->Value );
         if ( myKeyName->Equals( "__Args" ) )
         {
            array<Object^>^myArgs = (array<Object^>^)myValue;
            for ( int myInt = 0; myInt < myArgs->Length; myInt++ )
               Console::WriteLine( "arg: {0} myValue: {1}", myInt, myArgs[ myInt ] );
         }

         if ( (myKeyName->Equals( "__MethodSignature" )) && (nullptr != myValue) )
         {
            array<Object^>^myArgs = (array<Object^>^)myValue;
            for ( int myInt = 0; myInt < myArgs->Length; myInt++ )
               Console::WriteLine( "arg: {0} myValue: {1}", myInt, myArgs[ myInt ] );
         }
      }

      Console::WriteLine( "myUrl1 {0} object URI{1}", myUrl, myObjectURI );
      myDictionary->default[ "__Uri" ] = myUrl;
      Console::WriteLine( "URI {0}", myDictionary->default[ "__URI" ] );
      
      IMessage^ myRetMsg = myMessageSink->SyncProcessMessage( myMesg );
      if ( dynamic_cast<IMethodReturnMessage^>(myRetMsg) )
      {
         IMethodReturnMessage^ myMethodReturnMessage = dynamic_cast<IMethodReturnMessage^>(myRetMsg);
      }

      
      Console::WriteLine( "MyProxy.Invoke - Finish" );
      return myRetMsg;
   }

};


//
// Main function that drives the whole sample
//
int main()
{
   ChannelServices::RegisterChannel( gcnew HttpChannel, false );
   Console::WriteLine( "Remoting Sample:" );
   Console::WriteLine( "Generate a new MyProxy using the Type" );
   Type^ myType = MyHelloService::typeid;
   String^ myUrl1 = "http://localhost/myServiceAccess.soap";
   MyProxy^ myProxy = gcnew MyProxy( myType,myUrl1 );
   Console::WriteLine( "Obtain the transparent proxy from myProxy" );
   MyHelloService^ myService = dynamic_cast<MyHelloService^>(myProxy->GetTransparentProxy());
   Console::WriteLine( "Calling the Proxy" );
   String^ myReturnString = myService->myFunction( "bill" );
   Console::WriteLine( "Checking result : {0}", myReturnString );
   if ( myReturnString->Equals( "Hi there bill, you are using .NET Remoting" ) )
   {
      Console::WriteLine( "myService.HelloMethod PASSED : returned {0}", myReturnString );
   }
   else
   {
      Console::WriteLine( "myService.HelloMethod FAILED : returned {0}", myReturnString );
   }
}
using System;
using System.Collections;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using Share;	

namespace MyNameSpace
{

   public class MyProxy : RealProxy
   {
      string myUrl;
      string myObjectURI;
      IMessageSink myMessageSink;

      public MyProxy(Type myType, string myUrl1)
         : base(myType)
      {

         myUrl = myUrl1;

         IChannel[] myRegisteredChannels = ChannelServices.RegisteredChannels;
         foreach (IChannel channel in myRegisteredChannels )
         {
            if (channel is IChannelSender)
            {
               IChannelSender myChannelSender = (IChannelSender)channel;

               myMessageSink = myChannelSender.CreateMessageSink(myUrl, null, out myObjectURI);
               if (myMessageSink != null)
                  break;
            }
         }

         if (myMessageSink == null)
         {
            throw new Exception("A supported channel could not be found for myUrl1:"+ myUrl);
         }
      }

      public override IMessage Invoke(IMessage myMesg)
      {
         Console.WriteLine("MyProxy.Invoke Start");

         if (myMesg is IMethodCallMessage)
            Console.WriteLine("IMethodCallMessage");

         if (myMesg is IMethodReturnMessage)
            Console.WriteLine("IMethodReturnMessage");

         Console.WriteLine("Message Properties");
         IDictionary myDictionary = myMesg.Properties;
         IDictionaryEnumerator myEnum = (IDictionaryEnumerator) myDictionary.GetEnumerator();

         while (myEnum.MoveNext())
         {
            object myKey = myEnum.Key;
            string myKeyName = myKey.ToString();
            object myValue = myEnum.Value;

            Console.WriteLine("{0} : {1}", myKeyName, myEnum.Value);
            if (myKeyName == "__Args")
            {
               object[] myArgs = (object[])myValue;
               for (int myInt = 0; myInt < myArgs.Length; myInt++)
                  Console.WriteLine("arg: {0} myValue: {1}", myInt, myArgs[myInt]);
            }

            if ((myKeyName == "__MethodSignature") && (null != myValue))
            {
               object[] myArgs = (object[])myValue;
               for (int myInt = 0; myInt < myArgs.Length; myInt++)
                  Console.WriteLine("arg: {0} myValue: {1}", myInt, myArgs[myInt]);
            }
         }

         Console.WriteLine("myUrl1 {0} object URI{1}",myUrl,myObjectURI);

         myDictionary["__Uri"] = myUrl;
         Console.WriteLine("URI {0}", myDictionary["__URI"]);
         IMessage myRetMsg = myMessageSink.SyncProcessMessage(myMesg);

         if (myRetMsg is IMethodReturnMessage)
         {
            IMethodReturnMessage myMethodReturnMessage = (IMethodReturnMessage)myRetMsg;
         }

         Console.WriteLine("MyProxy.Invoke - Finish");
         return myRetMsg;
      }
   }

   //
   // Main class that drives the whole sample
   //
   public class ProxySample
   {
      public static void Main()
      {
         ChannelServices.RegisterChannel(new HttpChannel());

         Console.WriteLine("Remoting Sample:");

         Console.WriteLine("Generate a new MyProxy using the Type");
         Type myType = typeof(MyHelloService);
         string myUrl1 = "http://localhost/myServiceAccess.soap";
         MyProxy myProxy = new MyProxy(myType, myUrl1);

         Console.WriteLine("Obtain the transparent proxy from myProxy");
         MyHelloService myService = (MyHelloService)myProxy.GetTransparentProxy();

         Console.WriteLine("Calling the Proxy");
         string myReturnString = myService.myFunction("bill");

         Console.WriteLine("Checking result : {0}", myReturnString);

         if (myReturnString == "Hi there bill, you are using .NET Remoting")
         {
            Console.WriteLine("myService.HelloMethod PASSED : returned {0}", myReturnString);
         }
         else
         {
            Console.WriteLine("myService.HelloMethod FAILED : returned {0}", myReturnString);
         }
      }
   }
}

Imports System.Collections
Imports System.Threading
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http
Imports System.Runtime.Remoting.Proxies
Imports System.Runtime.Remoting.Messaging
Imports System.Security.Permissions
Imports Share


Namespace MyNameSpace

   Public Class MyProxy
      Inherits RealProxy
      Private myUrl As String
      Private myObjectURI As String
      Private myMessageSink As IMessageSink

      <PermissionSet(SecurityAction.LinkDemand)> _
      Public Sub New(myType As Type, myUrl1 As String)
         MyBase.New(myType)

         myUrl = myUrl1

         Dim myRegisteredChannels As IChannel() = ChannelServices.RegisteredChannels

         Dim channel As IChannel
         For Each channel In  myRegisteredChannels
            If TypeOf channel Is IChannelSender Then
               Dim myChannelSender As IChannelSender = CType(channel, IChannelSender)

               myMessageSink = myChannelSender.CreateMessageSink(myUrl, Nothing, myObjectURI)
               If Not (myMessageSink Is Nothing) Then
                  Exit For
               End If
            End If
         Next channel
         If myMessageSink Is Nothing Then
            Throw New Exception("A supported channel could not be found for myUrl1:" + myUrl)
         End If
      End Sub

      <SecurityPermission(SecurityAction.LinkDemand, Flags := SecurityPermissionFlag.Infrastructure)> _
      Public Overrides Function Invoke(ByVal myMesg As IMessage) As IMessage
         Console.WriteLine("MyProxy.Invoke Start")

         If TypeOf myMesg Is IMethodCallMessage Then
            Console.WriteLine("IMethodCallMessage")
         End If
         If TypeOf myMesg Is IMethodReturnMessage Then
            Console.WriteLine("IMethodReturnMessage")
         End If

         Console.WriteLine("Message Properties")
         Dim myDictionary As IDictionary = myMesg.Properties
         Dim myEnum As IDictionaryEnumerator = CType(myDictionary.GetEnumerator(), IDictionaryEnumerator)

         While myEnum.MoveNext()
            Dim myKey As Object = myEnum.Key
            Dim myKeyName As String = myKey.ToString()
            Dim myValue As Object = myEnum.Value

            Console.WriteLine( "{0} : {1}", myKeyName, myEnum.Value)
            If myKeyName = "__Args" Then
               Dim myArgs As Object() = CType(myValue, Object())
               Dim myInt As Integer
               For myInt = 0 To myArgs.Length - 1
                  Console.WriteLine(  "arg: {0} myValue: {1}", myInt, myArgs(myInt))
               Next myInt
            End If
            If myKeyName = "__MethodSignature" And Not (myValue Is Nothing) Then
               Dim myArgs As Object() = CType(myValue, Object())
               Dim myInt As Integer
               For myInt = 0 To myArgs.Length - 1
                  Console.WriteLine("arg: {0} myValue: {1}", myInt, myArgs(myInt))
               Next myInt
            End If
         End While

         Console.WriteLine("myUrl1 {0} object URI{1}", myUrl, myObjectURI)

         myDictionary("__Uri") = myUrl
         Console.WriteLine("URI {0}", myDictionary("__URI"))

         Dim myRetMsg As IMessage = myMessageSink.SyncProcessMessage(myMesg)

         If TypeOf (myRetMsg) Is IMethodReturnMessage Then
            Dim myMethodReturnMessage As IMethodReturnMessage = CType(myRetMsg, IMethodReturnMessage)
         End If

         Console.WriteLine("MyProxy.Invoke - Finish")
         Return myRetMsg
      End Function 'Invoke
   End Class

   '
   ' Main class that drives the whole sample
   '
   Public Class ProxySample
      <PermissionSet(SecurityAction.LinkDemand)> _
      Public Shared Sub Main()
         ChannelServices.RegisterChannel(New HttpChannel())

         Console.WriteLine("Remoting Sample:")

         Console.WriteLine("Generate a new MyProxy using the Type")
         Dim myType As Type = GetType(MyHelloService)
         Dim myUrl1 As String = "http://localhost/myServiceAccess.soap"
         Dim myProxy As New MyProxy(myType, myUrl1)

         Console.WriteLine("Obtain the transparent proxy from myProxy")
         Dim myService As MyHelloService = CType(myProxy.GetTransparentProxy(), MyHelloService)

         Console.WriteLine("Calling the Proxy")
         Dim myReturnString As String = myService.myFunction("bill")

         Console.WriteLine("Checking result : {0}", myReturnString)

         If myReturnString = "Hi there bill, you are using .NET Remoting" Then
            Console.WriteLine("myService.HelloMethod PASSED : returned {0}", myReturnString)
         Else
            Console.WriteLine("myService.HelloMethod FAILED : returned {0}", myReturnString)
         End If
      End Sub
   End Class
End Namespace 'MyNameSpace

Comentarios

Cuando se realiza una llamada de método en el proxy, la infraestructura de comunicación remota proporciona la compatibilidad necesaria para pasar los argumentos al objeto real a través de los límites de comunicación remota, llamar al método de objeto real con los argumentos y devolver los resultados al cliente del objeto proxy.

Una llamada a método remoto es un mensaje que va del extremo del cliente al extremo del servidor y, posiblemente, de nuevo. A medida que cruza los límites de comunicación remota en el camino, la llamada al método remoto pasa a través de una cadena de IMessageSink objetos. Cada receptor de la cadena recibe el objeto de mensaje, realiza una operación específica y delega al siguiente receptor de la cadena. El objeto proxy contiene una referencia a la primera IMessageSink que debe usar para iniciarse fuera de la cadena.

En el caso de las llamadas asincrónicas, en el momento de la delegación, cada receptor proporciona un receptor de respuesta (otro IMessageSink) al que llamará el siguiente receptor cuando la respuesta vuelva.

Los diferentes tipos de receptores realizan diferentes operaciones, según el tipo de objeto de mensaje recibido. Por ejemplo, un receptor podría provocar que se tome un bloqueo, otro podría aplicar la seguridad de las llamadas, otro podría realizar servicios de control de llamadas de flujo y confiabilidad, y otro podría transportar la llamada a un equipo , proceso o diferente AppDomain. Dos o más receptores de mensajes de la cadena pueden interactuar entre sí con respecto a cada acción específica.

Notas a los implementadores

Es importante tener en cuenta que el código que implementa la interfaz actual debe proporcionar implementaciones para SyncProcessMessage(IMessage) y AsyncProcessMessage(IMessage, IMessageSink), ya que las llamadas sincrónicas se pueden convertir en llamadas asincrónicas y viceversa. Ambos métodos se deben implementar, incluso si el receptor no admite el procesamiento asincrónico.

Propiedades

NextSink

Obtiene el siguiente receptor de mensajes en la cadena de receptores.

Métodos

AsyncProcessMessage(IMessage, IMessageSink)

Procesa, de forma asincrónica, el mensaje especificado.

SyncProcessMessage(IMessage)

Procesa, de forma sincrónica, el mensaje especificado.

Se aplica a