繁体   English   中英

.NET Remoting:如何处理断开连接的对象

[英].NET Remoting: How to handle disconnected objects

首先,让我解释一下我的设置。 我的服务器被设置为Marshaled单例对象:

 RemotingServices.Marshal(lsServer, ServerObject.objectUri);

为了从服务器到客户端进行双向通信,客户端激活ServerObject,然后传入自己的ClientObject(也是MarshalByRefObject),服务器使用ClientObject与客户端进行对话:

var lsClient = new ClientObject();

var lsServer = (ServerObject)Activator.GetObject(typeof(ServerObject), url);
lsServer.attach(lsClient);

调用attach方法时,服务器获取ClientObject并将其存储在List中:

public void attach(ClientObject client) {
    clientList.Add(client);
}

然后,服务器可以调用名为“SendMessage”的ClientObject上的方法,以便与其列表中的每个客户端进行通信:

foreach(var c in clientList) {
    c.SendMessage("Hello");
}

这种方法很有效,直到遇到断开连接的客户端。 在这种情况下,会拒绝客户端拒绝连接的错误。 我可以捕获错误,但问题是我无法从服务器的List中删除对ClientObject的引用。 以下在客户端断开连接时重新抛出“连接被拒绝”异常:

clientList.Remove(badClient);

所以有几个问题:

1-有没有办法检测客户端的连接状态而不必捕获错误?

2-当我检测到已断开连接的客户端时,为什么从服务器列表中删除对象的尝试似乎与客户端“通信”(从而导致再次抛出异常?)

编辑

正如Patrick在下面指出的那样,从列表中删除会导致List迭代我的对象并对它们进行比较(调用.Equals) - 这就是导致我的ClientObject再次尝试通信并因此抛出异常的原因。

为了解决这个问题,我改为将List更改为一个字典,该字典是在我的客户端连接到服务器时提供的唯一ID。 然后我使用该唯一ID删除客户端。

我从来没有找到一种直接的方法来确定客户端是否已断开连接而不是捕获错误。

在#2上不确定。 但是,如果您尝试从foreach循环内部从clientList删除项目,则不能。 这是一个.NET规则 - 在枚举时不会更改可枚举对象的内容。

相反,如果您在foreach循环中捕获错误,请将其存储在另一个列表中(“已断开连接”列表)。 在foreach之后,从clientList删除所有断开连接的项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM