Во-первых, позвольте мне немного рассказать о моей настройке. Мой сервер настроен как выстраивали единственный объект:.NET Remoting: Как обрабатывать отключенные объекты
RemotingServices.Marshal(lsServer, ServerObject.objectUri);
Для того, чтобы иметь двустороннюю связь с сервера к клиенту, клиент активирует ServerObject, затем проходит в своем собственном ClientObject (который также является MarshalByRefObject) сервер использует ClientObject говорить клиенту:
var lsClient = new ClientObject();
var lsServer = (ServerObject)Activator.GetObject(typeof(ServerObject), url);
lsServer.attach(lsClient);
Когда присоединять метод вызывается, сервер принимает ClientObject и сохраняет его в списке:
public void attach(ClientObject client) {
clientList.Add(client);
}
Затем
Сервер может вызвать метод на ClientObject под названием «SendMessage» сообщать каждому клиенту в его списке:
foreach(var c in clientList) {
c.SendMessage("Hello");
}
Это прекрасно работает до тех пор, пока клиент не встречается, что отключился. В этом случае возникает ошибка, когда клиент отказывается от соединения. Я могу поймать ошибку, но проблема в том, что я не могу удалить ссылку на ClientObject из Списка сервера. Следующие повторно бросает «отказ в соединении» исключение в любое время клиент был отключен:
clientList.Remove(badClient);
Так пара вопросов:
1 Есть ли способ для определения состояния соединения клиента без ловить ошибку?
2- Когда я обнаружить клиента, который отсоединен, почему попытка удалить объект из списка сервера появится «общаться» с клиентом (тем самым вызывая исключение бросить снова?)
EDIT
Как Патрик указал ниже, делая Удалить из списка вызывает список, чтобы перебирать свои объекты и сделать сравнение на них (вызов .equals) - это то, что вызвало мое ClientObject пытаться снова общаться и, таким образом, исключение.
Чтобы решить эту проблему, я вместо этого изменил список на словарь, на который был установлен уникальный идентификатор, предоставленный моим Клиентом во время присоединения к серверу. Затем я использовал этот уникальный идентификатор, чтобы удалить клиента.
Я никогда не нашел прямого способа определить, был ли клиент отключен, кроме обнаружения ошибки.
Спасибо, на самом деле я не удаляю его из списка во время цикла For. Эта ошибка является чем-то чем-то невозможным для изменения коллекции. Когда я выполняю clientList.Remove (badClient), он бросает исключение «Отказано в подключении» ...что кажется странным, но, похоже, просто ссылаясь на «badClient», он пытается использовать объект для связи с клиентом. – bugfixr
Что такое clientList - список? Сначала метод Remove делает IndexOf, чтобы увидеть, действительно ли объект, который вы передали, в коллекции. Под обложками IndexOf может вызывать либо оператор Equals вашего объекта, либо, возможно, GetHashCode(). Любой из этих вызовов будет отправлен по кабелю - и, таким образом, приведет к дополнительному исключению связи. –
PatrickSteele
Да, это список - это имеет смысл тогда. –
bugfixr