@@ -40,7 +40,9 @@ import io.socket.client.Socket;
|
||||
public class WebRTCManager {
|
||||
|
||||
private static final String TAG = "WebRTCManager";
|
||||
private static final String SIGNALING_SERVER_URL = "https://your-signaling-server.com"; // Replace with your server
|
||||
private static final String SIGNALING_SERVER_URL = "http://10.0.2.2:3000"; // For Android emulator
|
||||
// For real device on same network, use: "http://192.168.1.XXX:3000"
|
||||
// For production: "https://your-server.com"
|
||||
|
||||
public interface WebRTCListener {
|
||||
void onMessageReceived(String senderNickname, String message);
|
||||
@@ -208,13 +210,25 @@ public class WebRTCManager {
|
||||
listener.onDisconnected();
|
||||
});
|
||||
|
||||
socket.on("joined-room", args -> {
|
||||
Log.d(TAG, "Successfully joined room");
|
||||
JsonObject data = gson.fromJson(args[0].toString(), JsonObject.class);
|
||||
String roomId = data.get("roomId").getAsString();
|
||||
// Room joined successfully, ready for WebRTC
|
||||
});
|
||||
|
||||
socket.on("user-joined", args -> {
|
||||
String userNickname = (String) args[0];
|
||||
JsonObject data = gson.fromJson(args[0].toString(), JsonObject.class);
|
||||
String userNickname = data.get("nickname").getAsString();
|
||||
listener.onUserJoined(userNickname);
|
||||
|
||||
// Initiate WebRTC connection for new user
|
||||
createOffer();
|
||||
});
|
||||
|
||||
socket.on("user-left", args -> {
|
||||
String userNickname = (String) args[0];
|
||||
JsonObject data = gson.fromJson(args[0].toString(), JsonObject.class);
|
||||
String userNickname = data.get("nickname").getAsString();
|
||||
listener.onUserLeft(userNickname);
|
||||
});
|
||||
|
||||
@@ -233,6 +247,13 @@ public class WebRTCManager {
|
||||
handleIceCandidate(data);
|
||||
});
|
||||
|
||||
socket.on("error", args -> {
|
||||
JsonObject data = gson.fromJson(args[0].toString(), JsonObject.class);
|
||||
String errorMessage = data.get("message").getAsString();
|
||||
Log.e(TAG, "Server error: " + errorMessage);
|
||||
listener.onError(errorMessage);
|
||||
});
|
||||
|
||||
socket.connect();
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -244,7 +265,10 @@ public class WebRTCManager {
|
||||
public void joinRoom(String nickname) {
|
||||
this.nickname = nickname;
|
||||
if (socket != null && socket.connected()) {
|
||||
socket.emit("join-room", nickname);
|
||||
JsonObject joinData = new JsonObject();
|
||||
joinData.addProperty("nickname", nickname);
|
||||
joinData.addProperty("roomId", "main-chat"); // Default room
|
||||
socket.emit("join-room", joinData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,48 +309,101 @@ public class WebRTCManager {
|
||||
}
|
||||
|
||||
private void handleOffer(JsonObject data) {
|
||||
SessionDescription offer = new SessionDescription(
|
||||
JsonObject offer = data.getAsJsonObject("offer");
|
||||
SessionDescription offerSdp = new SessionDescription(
|
||||
SessionDescription.Type.OFFER,
|
||||
data.get("sdp").getAsString()
|
||||
offer.get("sdp").getAsString()
|
||||
);
|
||||
|
||||
peerConnection.setRemoteDescription(new SdpObserver(), offer);
|
||||
peerConnection.setRemoteDescription(new SdpObserver(), offerSdp);
|
||||
|
||||
// Create answer
|
||||
MediaConstraints constraints = new MediaConstraints();
|
||||
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
|
||||
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
|
||||
|
||||
peerConnection.createAnswer(new SdpObserver() {
|
||||
@Override
|
||||
public void onCreateSuccess(SessionDescription sessionDescription) {
|
||||
Log.d(TAG, "Answer created successfully");
|
||||
peerConnection.setLocalDescription(new SdpObserver(), sessionDescription);
|
||||
|
||||
JsonObject answerData = new JsonObject();
|
||||
answerData.addProperty("type", sessionDescription.type.canonicalForm());
|
||||
answerData.addProperty("sdp", sessionDescription.description);
|
||||
JsonObject answer = new JsonObject();
|
||||
answer.addProperty("type", sessionDescription.type.canonicalForm());
|
||||
answer.addProperty("sdp", sessionDescription.description);
|
||||
answerData.add("answer", answer);
|
||||
|
||||
// Send to the specific user who sent the offer
|
||||
if (data.has("fromSocketId")) {
|
||||
answerData.addProperty("targetSocketId", data.get("fromSocketId").getAsString());
|
||||
}
|
||||
|
||||
socket.emit("answer", answerData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateFailure(String error) {
|
||||
Log.e(TAG, "Failed to create answer: " + error);
|
||||
listener.onError("Failed to create answer: " + error);
|
||||
}
|
||||
}, constraints);
|
||||
}
|
||||
|
||||
private void handleAnswer(JsonObject data) {
|
||||
SessionDescription answer = new SessionDescription(
|
||||
JsonObject answer = data.getAsJsonObject("answer");
|
||||
SessionDescription answerSdp = new SessionDescription(
|
||||
SessionDescription.Type.ANSWER,
|
||||
data.get("sdp").getAsString()
|
||||
answer.get("sdp").getAsString()
|
||||
);
|
||||
|
||||
peerConnection.setRemoteDescription(new SdpObserver(), answer);
|
||||
peerConnection.setRemoteDescription(new SdpObserver(), answerSdp);
|
||||
}
|
||||
|
||||
private void handleIceCandidate(JsonObject data) {
|
||||
JsonObject candidateObj = data.getAsJsonObject("candidate");
|
||||
IceCandidate iceCandidate = new IceCandidate(
|
||||
data.get("sdpMid").getAsString(),
|
||||
data.get("sdpMLineIndex").getAsInt(),
|
||||
data.get("candidate").getAsString()
|
||||
candidateObj.get("sdpMid").getAsString(),
|
||||
candidateObj.get("sdpMLineIndex").getAsInt(),
|
||||
candidateObj.get("candidate").getAsString()
|
||||
);
|
||||
|
||||
peerConnection.addIceCandidate(iceCandidate);
|
||||
}
|
||||
|
||||
private void createOffer() {
|
||||
if (peerConnection == null) {
|
||||
Log.w(TAG, "PeerConnection not initialized when creating offer");
|
||||
return;
|
||||
}
|
||||
|
||||
MediaConstraints constraints = new MediaConstraints();
|
||||
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
|
||||
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
|
||||
|
||||
peerConnection.createOffer(new SdpObserver() {
|
||||
@Override
|
||||
public void onCreateSuccess(SessionDescription sessionDescription) {
|
||||
Log.d(TAG, "Offer created successfully");
|
||||
peerConnection.setLocalDescription(new SdpObserver(), sessionDescription);
|
||||
|
||||
JsonObject offerData = new JsonObject();
|
||||
JsonObject offer = new JsonObject();
|
||||
offer.addProperty("type", sessionDescription.type.canonicalForm());
|
||||
offer.addProperty("sdp", sessionDescription.description);
|
||||
offerData.add("offer", offer);
|
||||
|
||||
socket.emit("offer", offerData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateFailure(String error) {
|
||||
Log.e(TAG, "Failed to create offer: " + error);
|
||||
listener.onError("Failed to create offer: " + error);
|
||||
}
|
||||
}, constraints);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (localVideoTrack != null) {
|
||||
localVideoTrack.dispose();
|
||||
@@ -389,9 +466,11 @@ public class WebRTCManager {
|
||||
Log.d(TAG, "onIceCandidate: " + iceCandidate);
|
||||
|
||||
JsonObject candidateData = new JsonObject();
|
||||
candidateData.addProperty("candidate", iceCandidate.sdp);
|
||||
candidateData.addProperty("sdpMid", iceCandidate.sdpMid);
|
||||
candidateData.addProperty("sdpMLineIndex", iceCandidate.sdpMLineIndex);
|
||||
JsonObject candidate = new JsonObject();
|
||||
candidate.addProperty("candidate", iceCandidate.sdp);
|
||||
candidate.addProperty("sdpMid", iceCandidate.sdpMid);
|
||||
candidate.addProperty("sdpMLineIndex", iceCandidate.sdpMLineIndex);
|
||||
candidateData.add("candidate", candidate);
|
||||
|
||||
socket.emit("ice-candidate", candidateData);
|
||||
}
|
||||
|
||||
Referencia en una nueva incidencia
Block a user