У меня есть проект, в котором я создаю чат-сервер, где люди (клиенты) подключаются и выбирают партнера для чата. Однако они общаются только тогда, когда оба клиента отправляют сообщение и видят то, что напечатал другой. Я хочу что-то вроде WhatsApp, где мы отправляем много сообщений одно за другим, не дожидаясь отправки другого клиента.
Я пытался создать класс потока, в котором я вызываю чат и другие вещи, но никогда не работал.
//this is the client.java and this is the part of the code where they start chatting
do {
System.out.print(dis.readUTF());
System.out.println(dis.readUTF());
send = in.next();
dos.writeUTF(send);
b = dis.readBoolean();
} while (b);
//this is part of the chatserver.java where the connection is done they start chatting
class handleClient implements Runnable {
private Socket s1;
private Socket s2;
private String name1;
private String name2;
public handleClient(Socket s1, Socket s2, String n1, String n2) {
this.s1 = s1;
this.s2 = s2;
this.name1 = n1;
this.name2 = n2;
}
@Override
public void run() {
String msg1 = "", msg2 = "";
boolean b;
try {
DataOutputStream dos1 = new DataOutputStream(s1.getOutputStream());
DataInputStream dis1 = new DataInputStream(s1.getInputStream());
DataOutputStream dos2 = new DataOutputStream(s2.getOutputStream());
DataInputStream dis2 = new DataInputStream(s2.getInputStream());
do {
dos1.writeUTF(name1 + ": ");
dos2.writeUTF(name2 + ": ");
dos2.writeUTF(name1 + ": " + msg1);
msg1 = dis1.readUTF();
dos1.writeUTF(name2 + ": " + msg2);
msg2 = dis2.readUTF();
b = !msg1.equals(name1 + " is out") && !msg2.equals(name2 + " is out");
dos1.writeBoolean(b);
dos2.writeBoolean(b);
} while (b);
dos1.close();
dis1.close();
dos2.close();
dis2.close();
s1.close();
s2.close();
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
спасибо, я попробую ваше предложение.
создайте сервер веб-сокетов, используя библиотеку, а затем используйте веб-сокет для выполнения своей работы (важно использовать такие протоколы, как веб-сокет, а не писать свои собственные правила)
Я не так хорошо знаком с веб-сокетом, их код - это все, что я знаю в программировании отсосов.




Как сказал @Mohsen fallahi, используйте веб-сокеты (вы получаете неявную неблокирующую функциональность)
Для чистого решения javascript см.: https://javascript.info/вебсокет
readUTF(), ну, читает строку UTF. Он не возвращается, пока не прочитает его. Вот почему вы хотите читать с разных клиентов параллельно, чтобы не имело значения, какой из них отправляет сообщение первым, оно будет прочитано и впоследствии может быть перенаправлено независимо от других. Один из способов сделать это — создать отдельную ветку чтения для каждого клиента.
Вот простой сервер чата (не хотел заниматься подбором клиентов, извините):
public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(5555);
List<DataOutputStream> doss = new ArrayList<>();
while (true) {
Socket client = server.accept();
synchronized(doss) {
doss.add(new DataOutputStream(client.getOutputStream()));
}
new Thread(new Runnable() {
public void run() {
try (DataInputStream dis = new DataInputStream(client.getInputStream())) {
while (true) { // <--------- per-client loop
String message=dis.readUTF();
synchronized (doss) {
for (DataOutputStream dos : doss)
dos.writeUTF(message);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
}
}
Он имеет центральное хранилище исходящих потоков (doss) и один поток на каждого клиента для чтения входящих потоков. Затем потоки считывают строку со своего клиента и пересылают ее во все исходящие потоки навсегда (внутренний цикл while(true)).
На стороне клиента циклы практически однострочные, один для чтения сообщения и отправки его на сервер, а другой для получения чего-то с сервера и вывода на экран:
public class ChatClient {
public static void main(String[] args) throws Exception {
Scanner s = new Scanner(System.in);
System.out.print("Enter your nick: ");
String name = s.nextLine();
Socket socket = new Socket("localhost", 5555);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
new Thread(new Runnable() {
public void run() {
try {
while (true) // <------- receiver loop, in thread
System.out.println(dis.readUTF());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
dos.writeUTF(name + " has joined the conversation");
while (true) // <------- sender loop
dos.writeUTF(name + ": " + s.nextLine());
}
}
Вещь работает с хардкодом localhost на порту 5555, вообще не обеспечивает обработки ошибок (сервер умирает при уходе клиента). Это должно было быть коротким.
спасибо, мне было трудно понять, как это сделать в другой теме, теперь я знаю, как
Вы должны выполнять чтение и запись в разных потоках или использовать неблокирующий ввод-вывод.