简体   繁体   English

Java - 服务器网络特定的客户端聊天

[英]Java - server networking specific client chat

I created a simple chat server that writes to all clients that is connected (I posted just the core code for simplicity) 我创建了一个简单的聊天服务器,写入所有连接的客户端(为了简单起见,我只发布了核心代码)

public class server extends Thread {

private Socket clientSocket;
private static ArrayList<Socket> sockets = new ArrayList<Socket>();

public server(Socket clientSocket) {
    this.clientSocket = clientSocket;
    sockets.add(clientSocket);
}

public void run() {
    while (true) {
        try {
            for(Socket s: sockets) {
            //write something
            //the for loop will send it to every socket in the array
            }
        } catch (Exception e) {
            //catch it
        }   
    }    
}
}   

Now I want to be more specific in what client I want to send the message to, just like how a real-world chat application will have different chat rooms. 现在我想更具体地说明我想要发送消息的客户端,就像真实世界的聊天应用程序将有不同的聊天室一样。

So if Client1 connects to the server, he will want to start a chat group named "Apple". 因此,如果Client1连接到服务器,他将要启动名为“Apple”的聊天组。 And then when Client2 and Client3 connects, they can choose to join the group "Apple". 然后当Client2和Client3连接时,他们可以选择加入“Apple”组。 Simultaneously, Client 4 will connect to the server and create another chat group called "Banana" where other clients can join in and talk there. 同时,客户端4将连接到服务器并创建另一个名为“Banana”的聊天组,其他客户可以加入并在那里聊天。

My understanding is that I need to somehow identify each client that the server accepts (I have no idea how to implement this). 我的理解是我需要以某种方式识别服务器接受的每个客户端(我不知道如何实现它)。 Then do I somehow put them all into their own array based on their group chat name? 然后根据他们的群聊名称以某种方式将它们全部放入自己的阵列中?

I've been searching for the past week sample codes that allow more than 1 group chat simultaneously but everything I've seen just caters towards 1 only. 我一直在搜索过去一周的示例代码,这些代码允许同时进行多个群组聊天,但我看到的所有内容都只适用于1。

The simplest solution is to use and hashmap with key = name of the room and value = a list of users in the chat. 最简单的解决方案是使用带有key = name的房间和hashmap,以及值=聊天中的用户列表。 In practice: 在实践中:

HashMap<String, ArrayList<Socket>> rooms = new HashMap<>();

When a new user connects, it shoud send a message with the name of the room he want joint and after that you can check if the room already exist or not: 当新用户连接时,它会发送一条消息,其中包含他想要联合的房间的名称,之后您可以检查该房间是否已经存在:

ArrayList<Socket> clientsList = rooms.get(roomName);
if(clientsList == null) {
    clientsList = new ArrayList<Socket>();
    rooms.put(roomName, clientsList);
}
clientsList.add(socket);

Another good idea could be to create a Client class that contains the Socket along with other information (eg the username). 另一个好主意可能是创建一个包含Socket的Client类以及其他信息(例如用户名)。

For performance aspect I suggest you to have a look at Java nio, nio2. 对于性能方面,我建议你看一下Java nio,nio2。 With nio you can handle connections in async way and dont waste 1 thread per connection. 使用nio,您可以以异步方式处理连接,并且不会浪费每个连接1个线程。 Standart socket impelementation has some drawbacks. Standart socket implementation有一些缺点。

As solution to your problem, I'd prefer to seperate header and content of a message sent/received. 作为您的问题的解决方案,我更愿意分开发送/接收的消息的标题和内容。 In header there will be source user, target user/group,etc information. 在标题中将有源用户,目标用户/组等信息。 Your client will understand and print messages into related chat windows with correct sender. 您的客户将理解并使用正确的发件人将消息打印到相关的聊天窗口。

On server side, you may have Users map which key is userName and value is User Object. 在服务器端,您可以让Users映射哪个键是userName,值是User Object。 ChatGroups map which key is groupName and value is list of user names. ChatGroups映射哪个键是groupName,值是用户名列表。 Since relation is many to many you need to keeps a user's all participated groups as well. 由于关系是多对多的,因此您需要保留用户的所有参与组。 Either put a groupNameList in User Object or define a seperate map. 将groupNameList放在用户对象中或定义单独的映射。

Listen client sockets onClose action (possible with nio) and remove user from groups or maps with ablocking mechanism (concurrency) 侦听客户端套接字onClose操作(可能使用nio)并使用ablocking机制(并发)从组或映射中删除用户

Also adding new group, user, etc needs thread concurrency as well. 另外添加新组,用户等也需要线程并发。

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

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