Каналы переключения Дистанционной работы.NET отдельно

У нас есть нечетная проблема с Дистанционной работой.NET. В основном у нас есть сервер, который регистрирует два TcpChannels в ChannelServices.RegisterChannel():

  1. Каждый слушает на порте 50000
  2. Другой слушает на порте 15000.

У нас затем есть клиент, который регистрирует TcpChannel, чтобы смочь связаться с сервером. Мы получаем объект с сервера путем вызова Activator.GetObject() с URI

"tcp://serverip:50000/objectname"

и это хорошо работает, клиентские подключения к серверу на порте 50000 и получает объект.

Однако, когда мы запускаем вызывающие методы для того объекта, соединение с каналом на порте 50000 отбрасывается, и новая связь установлена с каналом на порте 15000 автоматически. Это создает настоящую проблему для нас, так как мы не хотим трафик в порте 15000, потому что тот канал не может быть связан с тем же сетевым адаптером как порт, 50 000 каналов на сервере или том порте не могут быть открыты в брандмауэре, который заставляет вызовы дистанционной работы перестать работать естественно.

Это очень странно для нас, так как клиент не знает в нашем коде, что там существует другой канал на сервере на порте 15000 или на каком IP он слушает, все же он пытается соединиться с ним.

Любая справка на этом значительно ценится,

Спасибо, Casper

Это - код, который настраивает один из каналов сервера, тот обычно на порте 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);
8
задан Patrick D'Souza 26 April 2013 в 16:27
поделиться

2 ответа

Мы зарегистрировали случай поддержки в Microsoft по этому поводу и, очевидно, то, что мы делаем здесь, не поддерживается .NET Remoting. Вам разрешено регистрировать только один канал каждого типа в одном AppDomain. Remoting делает то, что он отправляет URI объекта обратно клиенту, чтобы сообщить ему, где он может получить доступ к данному объекту. Когда он это делает, он просматривает зарегистрированные каналы на стороне сервера и использует первый канал, который он там находит, который соответствует запрашиваемому типу (в нашем случае: Tcp). Другими словами, он будет использовать тот канал, который окажется зарегистрированным первым. Его совершенно не волнует, по какому каналу подключился клиент.

Решение состоит в том, чтобы реализовать собственный IClientChannelSinkProvider на стороне клиента. Когда вы реализуете метод CreateSink(), вы можете выбрать, к какому url вы хотите, чтобы клиент подключался, когда вы создаете sink для использования.

9
ответ дан 5 December 2019 в 18:57
поделиться

Я тоже боролся с этими портами с "обратными ссылками"; Я думал, что это произойдет только в том случае, если сервер захочет отправить что-то обратно (даже в процедуре события). Поскольку у меня всегда были проблемы с межсетевыми экранами, я переключился на GenuineChannels (хотя я думаю, что это немного устарело).

0
ответ дан 5 December 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: