.NET удаленные каналы переключения само по себе

StackOverflow https://stackoverflow.com/questions/2818810

  •  26-09-2019
  •  | 
  •  

Вопрос

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

  1. Один слушает по порту 50000
  2. Другое слушает по порту 15000.

Затем у нас есть клиент, который регистрирует TCPChannel, чтобы иметь возможность взаимодействовать с сервером. Мы извлекаем объект с сервера, позвонив Activator.GetObject() с УРИ

«TCP: // Serverip: 50000 / ObjectName»

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

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

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

Любая помощь по этому признателю,

Спасибо, Каспер

Это код, который устанавливает один из серверных каналов, один обычно на порту 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);
Это было полезно?

Решение

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top