IMessageSink 介面
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
定義訊息匯入器的介面。
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
備註
當在代理上呼叫方法時,遠端化基礎設施提供必要的支援,將參數傳達給實體物件,並呼叫帶有參數的實際物件方法,並將結果回傳給代理物件的用戶端。
遠端方法呼叫是從用戶端到伺服器端,可能再回傳的訊息。 當遠端方法呼叫穿越遠端邊界時,會經過一連 IMessageSink 串物件。 鏈中的每個匯接收訊息物件,執行特定操作,並將任務委派給鏈中的下一個匯。 代理物件包含它需要用來啟動鏈的第一個 IMessageSink 參考。
對於非同步通話,在委派時,每個匯都會提供一個回應匯(另一個 IMessageSink),當回應回傳時,下一個匯會呼叫該匯。
不同類型的匯入會執行不同的操作,取決於接收到的訊息物件類型。 例如,一個匯流器可能導致鎖被奪取,另一個能強制呼叫安全,另一個能執行流量呼叫控制與可靠性服務,還有一個能將通話傳送到不同的 AppDomain程序或電腦。 鏈中兩個或以上的訊息匯可以彼此互動,針對每個特定動作。
給實施者的注意事項
值得注意的是,實作目前介面的程式碼必須同時提供 和 SyncProcessMessage(IMessage)的實作AsyncProcessMessage(IMessage, IMessageSink),因為同步呼叫可以轉換成非同步呼叫,反之亦然。 即使匯不支援非同步處理,這兩種方法都必須實作。
屬性
| 名稱 | Description |
|---|---|
| NextSink |
接到下一個訊息的匯入。 |
方法
| 名稱 | Description |
|---|---|
| AsyncProcessMessage(IMessage, IMessageSink) |
非同步處理給定訊息。 |
| SyncProcessMessage(IMessage) |
同步處理給定訊息。 |