简体   繁体   English

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

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

First, let me explain a little bit about my setup. 首先,让我解释一下我的设置。 My server is setup as a Marshaled singleton object: 我的服务器被设置为Marshaled单例对象:

 RemotingServices.Marshal(lsServer, ServerObject.objectUri);

In order to have two-way communication from the server to the client, the client activates a ServerObject, then passes in its own ClientObject (which is also a MarshalByRefObject) the server uses the ClientObject to talk back to the client: 为了从服务器到客户端进行双向通信,客户端激活ServerObject,然后传入自己的ClientObject(也是MarshalByRefObject),服务器使用ClientObject与客户端进行对话:

var lsClient = new ClientObject();

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

When the attach method is called, the server takes the ClientObject and stores it in a List: 调用attach方法时,服务器获取ClientObject并将其存储在List中:

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

The server can then call a method on the ClientObject called "SendMessage" to communicate to each client in its list: 然后,服务器可以调用名为“SendMessage”的ClientObject上的方法,以便与其列表中的每个客户端进行通信:

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

This works great until a client is encountered that has disconnected. 这种方法很有效,直到遇到断开连接的客户端。 In this case, an error is thrown about the client refusing the connection. 在这种情况下,会拒绝客户端拒绝连接的错误。 I can catch the error, but the problem is I cannot remove the reference to the ClientObject from the server's List. 我可以捕获错误,但问题是我无法从服务器的List中删除对ClientObject的引用。 The following re-throws the "connection refused" exception anytime a client has been disconnected: 以下在客户端断开连接时重新抛出“连接被拒绝”异常:

clientList.Remove(badClient);

So a couple of questions: 所以有几个问题:

1- Is there a way to detect the connection state of a client without having to catch an error? 1-有没有办法检测客户端的连接状态而不必捕获错误?

2- When I do detect a client that has disconnected, why does the attempt to remove the object from the server's list appear to "communicate" with the client (thus causing the exception to be thrown again?) 2-当我检测到已断开连接的客户端时,为什么从服务器列表中删除对象的尝试似乎与客户端“通信”(从而导致再次抛出异常?)

EDIT 编辑

As Patrick pointed out below, doing a Remove from a list causes the List to iterate my objects and do a comparison on them (calling .Equals) - this is what caused my ClientObject to attempt to communicate again and thus throw the exception. 正如Patrick在下面指出的那样,从列表中删除会导致List迭代我的对象并对它们进行比较(调用.Equals) - 这就是导致我的ClientObject再次尝试通信并因此抛出异常的原因。

To resolve it, I instead changed the List to a dictionary keyed off a unique ID supplied by my Client at the time of attaching to the server. 为了解决这个问题,我改为将List更改为一个字典,该字典是在我的客户端连接到服务器时提供的唯一ID。 Then I used that unique ID to remove the client. 然后我使用该唯一ID删除客户端。

I never did find a direct way for determining if a client had disconnected other than catching the error. 我从来没有找到一种直接的方法来确定客户端是否已断开连接而不是捕获错误。

Not sure on #2. 在#2上不确定。 However, if you're trying to remove an item from clientList from inside the foreach loop, you can't. 但是,如果您尝试从foreach循环内部从clientList删除项目,则不能。 That's a .NET rule -- no changing the contents of an enumerable object while it's being enumerated. 这是一个.NET规则 - 在枚举时不会更改可枚举对象的内容。

Instead, if you catch the error inside the foreach loop, store it in another list (a "disconnected" list). 相反,如果您在foreach循环中捕获错误,请将其存储在另一个列表中(“已断开连接”列表)。 After the foreach, remove all of the disconnected items from the clientList . 在foreach之后,从clientList删除所有断开连接的项目。

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

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