Compartilhar via


IMessageSink Interface

Definição

Define a interface para o coletor de mensagens.

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

Exemplos

O exemplo de código a seguir mostra a implementação da IMessageSink interface . Observe que o exemplo pressupõe definições de tipo e referências de assembly que devem ser fornecidas para o exemplo a ser compilado.

#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

Comentários

Quando uma chamada de método é feita no proxy, a infraestrutura de comunicação remota fornece o suporte necessário para passar os argumentos para o objeto real entre os limites de comunicação remota, chamar o método de objeto real com os argumentos e retornar os resultados de volta para o cliente do objeto proxy.

Uma chamada de método remoto é uma mensagem que vai da extremidade do cliente para a extremidade do servidor e, possivelmente, de volta. À medida que ultrapassa os limites de comunicação remota no caminho, a chamada de método remoto passa por uma cadeia de IMessageSink objetos. Cada coletor na cadeia recebe o objeto de mensagem, executa uma operação específica e delega para o próximo coletor na cadeia. O objeto proxy contém uma referência à primeira IMessageSink que precisa usar para iniciar a cadeia.

Para chamadas assíncronas, no momento da delegação, cada coletor fornece um coletor de resposta (outro IMessageSink) que será chamado pelo próximo coletor quando a resposta estiver voltando.

Diferentes tipos de coletores executam operações diferentes, dependendo do tipo de objeto de mensagem recebido. Por exemplo, um coletor pode fazer com que um bloqueio seja feito, outro poderia impor a segurança da chamada, outro poderia executar serviços de controle de chamada de fluxo e confiabilidade e outro poderia transportar a chamada para um , processo ou computador diferente AppDomain. Dois ou mais coletores de mensagens na cadeia podem interagir entre si em relação a cada ação específica.

Notas aos Implementadores

É importante observar que o código que implementa a interface atual deve fornecer implementações para SyncProcessMessage(IMessage) e AsyncProcessMessage(IMessage, IMessageSink), uma vez que chamadas síncronas podem ser convertidas em chamadas assíncronas e vice-versa. Ambos os métodos devem ser implementados, mesmo que o coletor não dê suporte ao processamento assíncrono.

Propriedades

NextSink

Obtém o próximo coletor de mensagem da cadeia de coletor.

Métodos

AsyncProcessMessage(IMessage, IMessageSink)

Processa de forma assíncrona a mensagem especificada.

SyncProcessMessage(IMessage)

Processa de forma síncrona a mensagem especificada.

Aplica-se a