8

.NETRemotingで奇妙な問題が発生しています。基本的に、2つのTcpChannelを登録するサーバーがありますChannelServices.RegisterChannel()

  1. 1つはポート50000でリッスンします
  2. もう1つは、ポート15000でリッスンします。

次に、サーバーと通信できるようにTcpChannelを登録するクライアントがあります。Activator.GetObject()URIを使用して呼び出すことにより、サーバーからオブジェクトを取得します

"tcp:// serverip:50000 / objectname"

これは正常に機能し、クライアントはポート50000でサーバーに接続し、オブジェクトを取得します。

ただし、そのオブジェクトでメソッドの呼び出しを開始すると、ポート50000のチャネルへの接続が切断され、ポート15000のチャネルへの新しい接続が自動的に確立されます。ポート15000のトラフィックがサーバーのポート50000チャネルと同じネットワークアダプタにバインドされていないか、ファイアウォールでそのポートが開いていない可能性があるため、これは私たちにとって実際の問題を引き起こします。リモーティングは自然に失敗するように呼びかけます。

クライアントは、ポート15000のサーバーに別のチャネルが存在することや、どのIPをリッスンしているのかをコードで認識していないため、これは非常に奇妙ですが、クライアントはそれに接続しようとします。

これに関する助けは大歓迎です、

ありがとう、キャスパー

これは、サーバーチャネルの1つ、通常はポート50000にあるチャネルを設定するコードです。

IDictionary props = new Hashtable();

props["port"] = m_tcpPort;
props["name"] = String.Empty;


BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

m_tcpChannel = new TcpServerChannel( props, /*clientProvider,*/ serverProvider );
ChannelServices.RegisterChannel( m_tcpChannel, false );

m_wellKnownObjRef = RemotingServices.Marshal( this, "Server@" + m_tcpPort.ToString() );

これは、通常はポート15000で他のサーバーチャネルを設定するコードです。

IDictionary props = new Hashtable();

props["name"] = String.Empty;
props["port"] = ip.Port;
props["bindTo"] = ip.Address.ToString();                    
props["timeout"] = REMOTING_TIMEOUT; // Timeout to prevent hung remoting calls.

if (!String.IsNullOrEmpty( machineName ))
{
    props["machineName"] = machineName;
}

    BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
    serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

    BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

    m_channel = new TcpChannel( props, clientProvider, serverProvider );
    ChannelServices.RegisterChannel( m_channel, false );

    m_objRef = RemotingServices.Marshal( this, QueueName ); // Queuename is a GUID.

これは、最初のサーバーチャネル(通常はポート50000にあるチャネル)に接続するクライアントのコードです。

IDictionary props = new Hashtable();

props["port"] = 0;

RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off;

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

m_tcpChannel = new TcpClientChannel(props, clientProvider/*, serverProvider*/);
ChannelServices.RegisterChannel(m_tcpChannel, false );

string address = "tcp://" + profile.RemoteIP + ":" + profile.RemoteTCP;

m_server = (Kernel)Activator.GetObject(typeof(Server), address + "/Server@" + port);
4

2 に答える 2

9

これについてMicrosoftにサポートケースを記録しましたが、ここで行っていることは.NETRemotingではサポートされていないようです。1つのAppDomainに登録できるのは各タイプのチャネルを1つだけです。Remotingが行うことは、オブジェクトのURIをクライアントに送り返し、問題のオブジェクトにアクセスできる場所をクライアントに通知することです。その場合、サーバー側で登録されたチャネルを調べ、要求されたタイプ(この場合はTcp)に一致する最初のチャネルを使用します。言い換えれば、最初に登録されるチャネルを使用します。クライアントがどのチャネルに接続しているかはまったく気にしません。

解決策は、クライアント側に独自のIClientChannelSinkProviderを実装することです。CreateSink()メソッドを実装すると、使用するシンクを作成するときにクライアントが接続するURLを選択できます。

于 2010-05-19T15:12:31.800 に答える
0

私はそれらの「バックリンクされた」ポートにも苦労しました。サーバーが何かを送り返したい場合にのみ発生すると思いました(イベント手順でも)。私は常にファイアウォールに問題があったので、GenuineChannelsに切り替えました(少し時代遅れだと思いますが)。

于 2010-05-19T12:23:20.017 に答える