从频道列表中删除客户端时遇到一些问题。
这是我目前拥有的代码:
服务器端:
private Hashtable<String, ArrayList<String>> channels = new Hashtable<String, ArrayList<String>>();
public synchronized void logMeOut(String username) throws RemoteException {
for(Client c : clients){
if(c.findName().equals(username)){
clients.remove(c);
disconnectAllChans(username);
System.out.println(username + " removed from clientlist.");
}
}
updateJListForOnlineUsers(); //Callback for other clients to update the userlist.
}
public void disconnectAllChans(String username) throws RemoteException{
for(Enumeration e = channels.elements(); e.hasMoreElements();){
if(channels.contains(username)){
channels.remove(username);
}
}
updateJListForUsersInChannel();
System.out.println("User " + username + " left all channel");
}
我已经尝试了if(channels.contains(username)和containsKey。他们似乎都不干这项工作。当我离开运行注销方法的服务器时,客户端只是挂起。我猜它在枚举循环中一直在循环。
编辑:客户端只有在加入频道时才会挂起。如果用户的频道列表为空,它会立即退出。
你知道代码应该是什么样子吗?
**
解决方案:
**
所以,是的,我想明白了,但如果没有你们,我是不会的。感谢
我只是在Brazzy发布的断开所有频道方法中运行了断开连接方法。结果如下:
@Override
public void disconnectChannel(String username, String channel) throws RemoteException{
if(isUserInChannelX(username, channel)){
channels.get(channel).remove(username);
String message = "User " + username + " left the channel.";
notifySelf(username, " You have left the channel " + channel);
notifyChannelSystem(channel, "SYSTEM", message);
updateJListForActiveChannels();
if(channels.get(channel).isEmpty()){
channels.remove(channel);
}
}
}
public void disconnectAllChans(String username) throws RemoteException{
for (String channel : channels.keySet()) {
ArrayList<String> members = channels.get(channel);
if (members.contains(username)) {
disconnectChannel(username, channel);
System.out.println("User " + username + " left channel " + channel);
}
}
updateJListForUsersInChannel();
}
我觉得有点傻^^谢谢大家!
您的代码中有一个无限循环:
for(Enumeration e = channels.elements(); e.hasMoreElements();){
if(channels.contains(username)){
channels.remove(username);
}
}
您永远不会从枚举e
中删除元素,因此e.hasMoreElements
将始终返回true。你可能想要更像这样的东西:
ArrayList<String> channel = null;
for(Enumeration e = channels.elements(); e.hasMoreElements(); channel = e.nextElement()){
if(channel.contains(username)){
channel.remove(username);
}
}
附带说明一下,您将在当前代码中遇到并发的修改错误。
将for替换为foreach循环,使其更难产生无限循环错误,就像您因未正确处理枚举器而陷入的错误一样:
for (String channel : channels.keySet()) {
ArrayList<String> members = channels.get(channel);
if (members.contains(username)) {
members.remove(username);
}
}
我想你想怎么做就怎么做。