IMessageSink 介面

定義

定義訊息接收的介面。

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
衍生
屬性

範例

下列程式代碼範例示範 介面的實作 IMessageSink 。 請注意,此範例會假設必須提供給範例進行編譯的類型定義和元件參考。

#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

備註

在 Proxy 上呼叫方法時,遠端基礎結構會提供將自變數傳遞至跨遠端界限之實際物件的必要支援、使用自變數呼叫實際物件方法,並將結果傳回 Proxy 物件的用戶端。

遠端方法呼叫是從用戶端到伺服器端的訊息,可能會再次返回。 當遠端界限在方式上跨越遠端界限時,遠端方法呼叫會通過 物件鏈 IMessageSink 結。 鏈結中的每個接收都會接收訊息對象、執行特定作業,以及委派給鏈結中的下一個接收。 Proxy 物件包含第一個需要用來啟動鏈結的 IMessageSink 參考。

針對異步呼叫,在委派時,每個接收都會提供回復接收 (另一 IMessageSink 個) ,當回復回到時,下一個接收會呼叫。

不同類型的接收會執行不同的作業,視收到的訊息物件類型而定。 例如,一個接收可能會導致鎖定,另一個接收可能會強制執行呼叫安全性、另一個可能會執行流程呼叫控制和可靠性服務,而另一個接收則可將呼叫傳輸至不同的 AppDomain、進程或計算機。 鏈結中的兩個或多個訊息接收可以彼此互動,以與每個特定動作有關。

給實施者的注意事項

請務必注意,實作目前介面的程式代碼必須同時提供 和AsyncProcessMessage(IMessage, IMessageSink)SyncProcessMessage(IMessage)實作,因為同步呼叫可以轉換成異步呼叫,反之亦然。 即使接收不支援異步處理,也必須實作這兩種方法。

屬性

NextSink

取得接收鏈結中的下一個訊息接收。

方法

AsyncProcessMessage(IMessage, IMessageSink)

非同步處理指定的訊息。

SyncProcessMessage(IMessage)

同步處理指定的訊息。

適用於