Java MultipleChat 带有语音消息,语音消息由客户端发送,但另一个客户端没有收到它
温馨提示:
本文最后更新于 2024年04月12日,已超过 48 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
We are implementing a Java multiple chat with sockets where with a server and multiple clients, a client needs to send a voice message and it has to be heard by another client. We have the class and the voice message is recorded but it never gets sent.
This is the Server class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
private static Set<PrintWriter> writers = new HashSet<>();
public static boolean calling = false;
public static Server_voice sv = new Server_voice();
public static void main(String[] args) {
sv.init_audio();
int PORT = 6789;
Chatters clientes = new Chatters();
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Servidor iniciado. Esperando clientes...");
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Nuevo cliente conectado: " + clientSocket);
// crea el objeto Runable
ClientHandler clientHandler = new ClientHandler(clientSocket, clientes);
// inicia el hilo con el objeto Runnable
new Thread(clientHandler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is the Client class:
import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
import java.util.Set;
import javax.sound.sampled.*;
import java.io.IOException;
public class Client {
private static final String SERVER_IP = "127.0.0.1";
private static final int PORT = 6789;
private static int AUDIO_PORT_RECEIVER;
private static int AUDIO_PORT_SENDER;
private static AudioRecorderPlayer recorderPlayer = new AudioRecorderPlayer();
public static void main(String[] args) {
try {
Socket socket = new Socket(SERVER_IP, PORT);
System.out.println("Connected to the server.");
// Generate available ports for audio sender and receiver
AUDIO_PORT_RECEIVER = findAvailablePort();
AUDIO_PORT_SENDER = findAvailablePort();
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
OutputStream outputStream = socket.getOutputStream();
Thread readerThread = new Thread(new Receiver(in, socket));
readerThread.start();
Thread senderThread = new Thread(new Sender(userInput, out, outputStream));
senderThread.start();
readerThread.join(); // Wait for the receiver thread to finish
senderThread.join(); // Wait for the sender thread to finish
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private static int findAvailablePort() throws IOException {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
}
}
static class Receiver implements Runnable {
private BufferedReader in;
private Socket socket;
public Receiver(BufferedReader in, Socket socket) {
this.in = in;
this.socket = socket;
}
@Override
public void run() {
try {
String receivedMessage;
while ((receivedMessage = in.readLine()) != null) {
if (receivedMessage.equals("audio")) {
// Receive audio
receiveAudio();
} else if(receivedMessage.equals("CALL")){
System.out.println("Llamada empezada!");
// Listen for the ip
String ip = in.readLine();
// Start the call
Set<String> ips = Set.of(ip);
Thread callSenderThread = new Thread(new CallSender(ips));
callSenderThread.start();
Thread callReceiverThread = new Thread(new CallReceiver());
callReceiverThread.start();
} else {
// Print other messages
System.out.println(receivedMessage);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void receiveAudio() throws IOException {
InputStream inputStream = socket.getInputStream();
int randomNumber = 1 + new Random().nextInt(100000);
String fileName = "./Client/audios/received_audio" + randomNumber + ".wav";
System.out.println("Audio file: " + fileName);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
new FileOutputStream(fileName));
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) > 0) {
bufferedOutputStream.write(buffer, 0, bytesRead);
// Check if the file transfer is complete
if (inputStream.available() == 0) {
break;
}
}
bufferedOutputStream.close();
System.out.println("Has recibido un audio, lo encontraras en la carpeta audios bajo el nombre: received_audio" + randomNumber + ".wav");
}
}
static class Sender implements Runnable {
private BufferedReader userInput;
private PrintWriter out;
private OutputStream outputStream;
public Sender(BufferedReader userInput, PrintWriter out, OutputStream outputStream) {
this.userInput = userInput;
this.out = out;
this.outputStream = outputStream;
}
@Override
public void run() {
try {
String message;
while ((message = userInput.readLine()) != null) {
if (message.startsWith("/record")) {
// Record audio and send
recordAndSendAudio(message);
} else {
out.println(message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void recordAndSendAudio(String message) throws IOException {
int duration = Integer.parseInt(message.split(" ")[1]);
recorderPlayer.recordAudio(duration);
out.println(message);
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("recorded_audio.wav"));
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
bufferedInputStream.close();
Path audioFilePath = Paths.get("recorded_audio.wav");
Files.deleteIfExists(audioFilePath);
}
}
static class CallSender implements Runnable {
private Set<String> ips;
public CallSender(Set<String> ips) {
this.ips = ips;
}
@Override
public void run() {
try {
// Initialize audio capture
AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
DatagramSocket socket = new DatagramSocket(AUDIO_PORT_SENDER);
byte[] buffer = new byte[1024];
while (true) {
// Capture audio
int bytesRead = line.read(buffer, 0, buffer.length);
// Send audio to all IPs
for (String ip : ips) {
InetAddress address = InetAddress.getByName(ip);
DatagramPacket packet = new DatagramPacket(buffer, bytesRead, address, AUDIO_PORT_RECEIVER);
socket.send(packet);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class CallReceiver implements Runnable {
@Override
public void run() {
try {
// Initialize audio playback
AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
// Initialize network socket
DatagramSocket socket = new DatagramSocket(AUDIO_PORT_RECEIVER);
byte[] buffer = new byte[1024];
while (true) {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// Play received audio
line.write(packet.getData(), 0, packet.getLength());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And the ClientHandler class:
import java.io.*;
import java.net.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.List;
class ClientHandler implements Runnable {
private Socket clientSocket;
private BufferedReader in;
private PrintWriter out;
private String clientName;
Chatters clientes;
// Constructor que recibe el socket del cliente y la lista de clientes del chat
public ClientHandler(Socket socket, Chatters clientes) {
this.clientSocket = socket;
this.clientes = clientes;
try {
// Se inicializan los flujos de entrada y salida
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
// Pedir al cliente que ingrese su nombre
while (true) {
out.println("Ingresa tu nombre");
clientName = in.readLine();
if (clientName == null) {
return;
}
synchronized (clientName) {
// Verificar si el nombre está disponible y agregar al usuario al chat
if (!clientName.isBlank() && !clientes.existeUsr(clientName)) {
clientes.broadcastMessage(clientName + " se ha unido al chat.");
out.println("NOMBRE ACEPTADO: " + clientName);
clientes.addUsr(clientName, out, clientSocket);
break;
}
}
}
String message;
// Esperar y manejar mensajes de los clientes
while ((message = in.readLine()) != null) {
if (message.startsWith("/createGroup")) {
handleCreateGroup(message);
} else if (message.startsWith("/join")) {
handleJoinGroup(message);
} else if (message.startsWith("/group")) {
handleGroupMessage(message);
} else if (message.startsWith("/leaveGroup")) {
handleLeaveGroup(message);
} else if (message.contains(":")) {
handlePrivateMessage(message);
} else if(message.startsWith("/recordAudio")){
handleRecordAudio(message, "grupo");
} else if(message.startsWith("/calling")){
new Thread(() -> {
try {
playCall();
} catch (Exception e) {
e.printStackTrace();
}
})
.start();
} else {
clientes.broadcastMessage(clientName + ": " + message);
}
}
} catch (IOException e) {
// Manejar errores de E/S
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// Cerrar el socket y eliminar al usuario del chat al salir
clientSocket.close();
System.out.println(clientName + " ha abandonado el chat.");
clientes.broadcastMessage(clientName + " ha abandonado el chat.");
clientes.removeUsr(clientName);
} catch (IOException e) {
// Manejar errores al cerrar el socket
}
}
}
private void handleJoinGroup(String message) {
String[] parts = message.split(" ");
if (parts.length >= 2) {
String groupName = parts[1];
clientes.addUserToGroup(groupName, new Person(clientName, out, clientSocket));
out.println("Te has unido al grupo '" + groupName + "'.");
}
}
private void handleGroupMessage(String message) {
String[] parts = message.split(" ", 3);
if (parts.length >= 3) {
String groupName = parts[1];
String groupMessage = parts[2];
clientes.sendMessageToGroup(groupName, clientName + ": " + groupMessage);
out.println("Mensaje enviado al grupo '" + groupName + "'.");
}
}
private void handleCreateGroup(String message) {
String[] parts = message.split(" ");
if (parts.length >= 2) {
String groupName = parts[1];
clientes.createGroup(groupName);
out.println("Grupo '" + groupName + "' creado correctamente.");
}
}
private void handleLeaveGroup(String message) {
String[] parts = message.split(" ");
if (parts.length >= 2) {
String groupName = parts[1];
clientes.removeUserFromGroup(groupName, clientName);
}
}
private void handlePrivateMessage(String message) {
String[] parts = message.split(":", 2);
String receiver = parts[0].trim();
String privateMessage = parts[1].trim();
clientes.sendMessageToUser(clientName, receiver, privateMessage);
}
// Nuevo método para manejar la grabación de audio
private void handleRecordAudio(String message, String groupName) {
try {
// Lógica para grabar el audio desde el socket del cliente y guardar en un archivo
System.out.println("Grabando audio...");
InputStream inputStream = this.clientSocket.getInputStream();
int randomNumber = 1 + new Random().nextInt(100000);
String fileName = "./db/received_audio" + randomNumber + ".wav";
System.out.println("Archivo de audio: " + fileName);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(fileName));
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) > 0) {
bufferedOutputStream.write(buffer, 0, bytesRead);
}
bufferedOutputStream.close();
// Obtener el tipo de envío (grupo o usuario) desde el mensaje
String sendOption = message.split(" ")[1]; // Cambiado a índice 1
System.out.println("sendOption: " + sendOption);
if (sendOption.equals("group")) {
handleGroupAudio(fileName, groupName);
} else if (sendOption.equals("user")) {
handleUserAudio(message, fileName);
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error al grabar audio.");
}
}
// Método para manejar el env<ío de audio a un grupo
private void handleGroupAudio(String fileName, String groupName) {
Set<Person> groupMembers = clientes.getGroup(groupName);
try {
for (Person member : groupMembers) {
Socket memberSocket = member.getSocket();
OutputStream outputStream = memberSocket.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(fileName);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = bufferedInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, bytesRead);
}
bufferedInputStream.close();
outputStream.close();
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error sending audio to group members.");
}
}
// Método para manejar el envío de audio a un usuario
private void handleUserAudio(String message, String fileName) {
String receiver = message.split(" ")[3];
try {
clientes.sendAudioToUser(receiver, clientName, fileName);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error sending audio to user.");
}
}
private void playCall() throws Exception {
DatagramSocket serverSocket = new DatagramSocket(6789);
System.out.println("\nServer started. Waiting for clients...\n");
// Configurar la línea de audio para reproducir el audio recibido
AudioFormat audioFormat = new AudioFormat(44100.0f, 16, 2, true, false);
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class,
audioFormat
);
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(
dataLineInfo
);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
byte[] receiveData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(
receiveData,
receiveData.length
);
serverSocket.receive(receivePacket);
// Reproducir audio
sourceDataLine.write(
receivePacket.getData(),
0,
receivePacket.getLength()
);
}
}
}
We have tried multiple changes between classes but more than fixing the issue it makes it worse, not even letting the client enter their users. The idea as described before is that the voice message gets to the other end (Client) and it gets heard, but is not happening.
正文到此结束
- 本文标签: 家庭宠物
- 本文链接: https://www.coder6.net/article/2367
- 版权声明: 本文由蚂蚁原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
热门推荐
-
浏览(192) 评论(0)