IMessageSink Interface

Definitie

Hiermee definieert u de interface voor een berichtsink.

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
Afgeleid
Kenmerken

Voorbeelden

In het volgende codevoorbeeld ziet u de implementatie van de IMessageSink interface. Houd er rekening mee dat in het voorbeeld wordt uitgegaan van typedefinities en assemblyverwijzingen die moeten worden opgegeven om het voorbeeld te compileren.

#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

Opmerkingen

Wanneer een methode-aanroep wordt gedaan op de proxy, biedt de externe infrastructuur de benodigde ondersteuning voor het doorgeven van de argumenten aan het werkelijke object over de externe grenzen, het aanroepen van de werkelijke objectmethode met de argumenten en het retourneren van de resultaten naar de client van het proxyobject.

Een aanroep van een externe methode is een bericht dat van het client-end naar het servereind gaat en mogelijk weer teruggaat. Wanneer de externe methode onderweg externe grenzen overschrijdt, loopt de aanroep van de externe methode door een keten van IMessageSink objecten. Elke sink in de keten ontvangt het berichtobject, voert een specifieke bewerking uit en delegeert naar de volgende sink in de keten. Het proxyobject bevat een verwijzing naar de eerste IMessageSink die moet worden gebruikt om de keten te starten.

Voor asynchrone oproepen, op het moment van delegatie, biedt elke sink een antwoordsink (een andere IMessageSink) die door de volgende sink wordt aangeroepen wanneer het antwoord terugkomt.

Verschillende typen sinks voeren verschillende bewerkingen uit, afhankelijk van het type berichtobject dat is ontvangen. Een sink kan bijvoorbeeld leiden tot een vergrendeling, een andere kan oproepbeveiliging afdwingen, een andere kan stroomoproepbeheer en betrouwbaarheidsservices uitvoeren, en nog een andere kan de oproep naar een ander AppDomain, proces of computer transporteren. Twee of meer berichtsinks in de keten kunnen met elkaar communiceren met betrekking tot elke specifieke actie.

Notities voor uitvoerders

Het is belangrijk om te weten dat code die de huidige interface implementeert, implementaties moet bieden voor zowel SyncProcessMessage(IMessage)AsyncProcessMessage(IMessage, IMessageSink)als, omdat synchrone aanroepen kunnen worden geconverteerd naar asynchrone aanroepen en vice versa. Beide methoden moeten worden geïmplementeerd, zelfs als de sink geen ondersteuning biedt voor asynchrone verwerking.

Eigenschappen

Name Description
NextSink

Hiermee haalt u de volgende berichtsink op in de sinkketen.

Methoden

Name Description
AsyncProcessMessage(IMessage, IMessageSink)

Asynchroon verwerkt het opgegeven bericht.

SyncProcessMessage(IMessage)

Verwerkt het opgegeven bericht synchroon.

Van toepassing op