Skip to content

Commit 091a313

Browse files
Initial commit
1 parent ebf5c0f commit 091a313

17 files changed

+367
-78
lines changed

src/main/java/com/example/webrtc/MediaStreamManager.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ private MediaStreamManager() {
99
// private constructor to hide the implicit public one
1010
}
1111

12-
public static String[] getRequestedUrls(String payload) {
12+
public static String[] parseRequestedUrls(String payload) {
1313
return payload.split(",");
1414
}
1515

16-
public static String[] getAvailableUrls(String[] requestedUrls) {
17-
return requestedUrls;
16+
public static String[] getAvailableUrls(String[] payload) {
17+
return payload;
1818
}
1919

2020
public static String[] getAvailableUrls(String payload) {
21-
return getAvailableUrls(getRequestedUrls(payload));
21+
return getAvailableUrls(parseRequestedUrls(payload));
2222
}
2323

2424
public static Object getMediaStream(String[] availableUrls, String from) {
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,76 @@
11
package com.example.webrtc;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.apache.logging.log4j.LogManager;
7+
import org.apache.logging.log4j.Logger;
8+
9+
import com.example.webrtc.model.WebRtcSignalingMessage;
10+
import com.fasterxml.jackson.core.JsonProcessingException;
11+
import com.fasterxml.jackson.databind.DeserializationFeature;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
314
import dev.onvoid.webrtc.RTCConfiguration;
415

516
public class PeerConnectionManager {
17+
private static final Logger logger = LogManager.getLogger(PeerConnectionManager.class);
18+
private static final RTCConfiguration config = new RTCConfiguration();
19+
private static final Map<String, WebRtcPeerConnection> peerConnections = new HashMap<>();
20+
621
private PeerConnectionManager() {
722
// Private constructor to hide the implicit public one
823
}
924

10-
public static void add(WebRtcWebSocketClient webSocketClient, RTCConfiguration config, String peer, String[] urls) {
11-
WebRtcPeerConnection peerConnection = new WebRtcPeerConnection(webSocketClient, config, peer, urls);
25+
public static void addOrUpdate(WebRtcWebSocketClient webSocketClient, RTCConfiguration config, String peer,
26+
String[] urls) {
27+
peerConnections.merge(peer, new WebRtcPeerConnection(webSocketClient, config, peer, urls),
28+
(key, existingConnection) -> existingConnection.update(urls));
1229
}
1330

31+
public static void addIceCandidate(WebRtcSignalingMessage message) {
32+
WebRtcPeerConnection connection = peerConnections.get(message.getFrom());
33+
if (connection == null) {
34+
logger.warn("No connection found for peer {}", message.getFrom());
35+
} else {
36+
connection.addIceCandidate(message.getPayload());
37+
}
38+
}
39+
40+
public static void addAnswer(String peer, String answer) {
41+
}
42+
43+
public static void closeConnection(WebRtcSignalingMessage message) {
44+
peerConnections.computeIfPresent(message.getFrom(), (key, connection) -> {
45+
try {
46+
connection.close();
47+
} catch (Exception e) {
48+
logger.error("Error closing connection for peer {}", message.getFrom(), e);
49+
}
50+
return null;
51+
});
52+
}
53+
54+
public static void addAnswer(WebRtcSignalingMessage message) {
55+
WebRtcPeerConnection connection = peerConnections.get(message.getFrom());
56+
if (connection == null) {
57+
logger.warn("No connection found for peer {}", message.getFrom());
58+
} else {
59+
try {
60+
connection.answer(message.toSdp());
61+
} catch (JsonProcessingException e) {
62+
logger.error("Error processing ANSWER message from {} as {}", message.getFrom(), e.getMessage());
63+
}
64+
}
65+
}
66+
67+
public static void addConfiguration(WebRtcSignalingMessage message) {
68+
try {
69+
ObjectMapper objectMapper = new ObjectMapper();
70+
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
71+
objectMapper.readerForUpdating(config).readValue(message.getPayload());
72+
} catch (Exception e) {
73+
logger.error("Error processing CONFIG message: {}", e.getMessage());
74+
}
75+
}
1476
}

src/main/java/com/example/webrtc/WebRTCPeerConnection.java

+170-2
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,192 @@
22

33
import org.apache.logging.log4j.LogManager;
44
import org.apache.logging.log4j.Logger;
5+
6+
import com.example.webrtc.model.WebRtcSignalingMessage;
7+
8+
import dev.onvoid.webrtc.CreateSessionDescriptionObserver;
59
import dev.onvoid.webrtc.PeerConnectionFactory;
10+
import dev.onvoid.webrtc.PeerConnectionObserver;
611
import dev.onvoid.webrtc.RTCConfiguration;
12+
import dev.onvoid.webrtc.RTCDataChannel;
13+
import dev.onvoid.webrtc.RTCIceCandidate;
14+
import dev.onvoid.webrtc.RTCIceConnectionState;
15+
import dev.onvoid.webrtc.RTCIceGatheringState;
16+
import dev.onvoid.webrtc.RTCOfferOptions;
717
import dev.onvoid.webrtc.RTCPeerConnection;
18+
import dev.onvoid.webrtc.RTCPeerConnectionIceErrorEvent;
19+
import dev.onvoid.webrtc.RTCPeerConnectionState;
20+
import dev.onvoid.webrtc.RTCRtpReceiver;
21+
import dev.onvoid.webrtc.RTCRtpTransceiver;
22+
import dev.onvoid.webrtc.RTCSdpType;
23+
import dev.onvoid.webrtc.RTCSessionDescription;
24+
import dev.onvoid.webrtc.RTCSignalingState;
25+
import dev.onvoid.webrtc.SetSessionDescriptionObserver;
26+
import dev.onvoid.webrtc.media.MediaStream;
827

928
public class WebRtcPeerConnection implements AutoCloseable {
1029
private static final Logger logger = LogManager.getLogger(WebRtcPeerConnection.class);
1130

1231
private final RTCPeerConnection peerConnection;
32+
private final String peer;
33+
34+
private WebRtcWebSocketClient webSocketClient;
1335

1436
public WebRtcPeerConnection(WebRtcWebSocketClient webSocketClient, RTCConfiguration config, String peer,
1537
String[] urls) {
38+
this.webSocketClient = webSocketClient;
39+
this.peer = peer;
40+
1641
this.peerConnection = new PeerConnectionFactory().createPeerConnection(config,
17-
new WebRtcPeerConnectionObserver(webSocketClient, peer));
42+
new PeerConnectionObserver() {
43+
@Override
44+
public void onConnectionChange(RTCPeerConnectionState state) {
45+
logger.info("Connection state changed to {} for peer {}", state, peer);
46+
}
47+
48+
@Override
49+
public void onSignalingChange(RTCSignalingState state) {
50+
logger.info("Signaling state changed to {} for peer {}", state, peer);
51+
}
52+
53+
@Override
54+
public void onIceCandidate(RTCIceCandidate candidate) {
55+
try {
56+
logger.info("Sending ICE candidate to peer {}", peer);
57+
webSocketClient.sendMessage(new WebRtcSignalingMessage(peer, candidate));
58+
} catch (Exception e) {
59+
logger.error("Unable to send ICE candidate to peer {}", peer, e);
60+
}
61+
}
62+
63+
@Override
64+
public void onIceConnectionChange(RTCIceConnectionState state) {
65+
logger.info("ICE connection state changed to {} for peer {}", state, peer);
66+
}
67+
68+
@Override
69+
public void onStandardizedIceConnectionChange(RTCIceConnectionState state) {
70+
logger.info("Standardized ICE connection state changed to {} for peer {}", state, peer);
71+
}
72+
73+
@Override
74+
public void onIceConnectionReceivingChange(boolean receiving) {
75+
logger.info("ICE connection receiving changed to {} for peer {}", receiving, peer);
76+
}
77+
78+
@Override
79+
public void onIceGatheringChange(RTCIceGatheringState state) {
80+
logger.info("ICE gathering state changed to {} for peer {}", state, peer);
81+
}
82+
83+
@Override
84+
public void onIceCandidatesRemoved(RTCIceCandidate[] candidates) {
85+
logger.info("ICE candidates removed for peer {}", peer);
86+
}
87+
88+
@Override
89+
public void onIceCandidateError(RTCPeerConnectionIceErrorEvent event) {
90+
logger.error("ICE candidate error for peer {} on event {}", peer, event);
91+
}
92+
93+
@Override
94+
public void onRemoveStream(MediaStream stream) {
95+
logger.info("Stream removed for peer {}", peer);
96+
}
97+
98+
@Override
99+
public void onDataChannel(RTCDataChannel dataChannel) {
100+
logger.info("Data channel created for peer {}", peer);
101+
}
102+
103+
@Override
104+
public void onAddTrack(RTCRtpReceiver receiver, MediaStream[] mediaStreams) {
105+
logger.info("Track added for peer {}", peer);
106+
}
107+
108+
@Override
109+
public void onRemoveTrack(RTCRtpReceiver receiver) {
110+
logger.info("Track removed for peer {}", peer);
111+
}
112+
113+
@Override
114+
public void onTrack(RTCRtpTransceiver transceiver) {
115+
logger.info("Track added for peer {}", peer);
116+
}
117+
});
118+
119+
init(urls);
120+
}
121+
122+
private void init(String[] urls) {
123+
logger.info("Initializing WebRTC peer connection of peer {}", peer);
124+
createOffer();
125+
}
126+
127+
private void createOffer() {
128+
peerConnection.createOffer(new RTCOfferOptions(), new CreateSessionDescriptionObserver() {
129+
130+
@Override
131+
public void onSuccess(RTCSessionDescription description) {
132+
logger.info("Setting local description for peer {}", peer);
133+
peerConnection.setLocalDescription(description, new SetSessionDescriptionObserver() {
134+
135+
@Override
136+
public void onSuccess() {
137+
logger.info("Sending offer to peer {}", peer);
138+
try {
139+
webSocketClient.sendMessage(new WebRtcSignalingMessage(peer, description));
140+
} catch (Exception e) {
141+
logger.error("Failed to send offer to peer {}", peer, e);
142+
}
143+
}
144+
145+
@Override
146+
public void onFailure(String error) {
147+
logger.error("Failed to set local description for peer {} as {}", peer, error);
148+
}
149+
});
150+
}
151+
152+
@Override
153+
public void onFailure(String error) {
154+
logger.error("Failed to create offer for peer {} as {}", peer, error);
155+
}
156+
});
18157
}
19158

20159
@Override
21160
public void close() throws Exception {
22-
logger.info("Closing WebRTC peer connection");
161+
logger.info("Closing WebRTC peer connection of peer {}", peer);
23162
peerConnection.close();
24163
}
164+
165+
public void addIceCandidate(String payload) {
166+
logger.info("Adding ICE candidate to WebRTC peer connection of peer {} with payload: {}", peer, payload);
167+
peerConnection.addIceCandidate(new RTCIceCandidate(null, 0, payload));
168+
}
169+
170+
public void answer(String payload) {
171+
logger.info("Answering WebRTC peer connection of peer {} with payload: {}", peer, payload);
172+
peerConnection.setRemoteDescription(new RTCSessionDescription(RTCSdpType.ANSWER, payload),
173+
new SetSessionDescriptionObserver() {
174+
175+
@Override
176+
public void onSuccess() {
177+
logger.info("Successfully set remote description for peer {}", peer);
178+
}
179+
180+
@Override
181+
public void onFailure(String error) {
182+
logger.error("Failed to set remote description for peer {} as {}", peer, error);
183+
}
184+
});
185+
}
186+
187+
public WebRtcPeerConnection update(String[] urls) {
188+
logger.info("Updating WebRTC peer connection of peer {} with new URLs: {}", peer, String.join(", ", urls));
189+
init(urls);
190+
return this;
191+
}
192+
25193
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
package com.example.webrtc;
22

3+
import java.util.concurrent.atomic.AtomicBoolean;
4+
35
import org.apache.logging.log4j.LogManager;
46
import org.apache.logging.log4j.Logger;
57

68
public class WebRtcMediator {
79
private static final Logger logger = LogManager.getLogger(WebRtcMediator.class);
10+
private static final AtomicBoolean running = new AtomicBoolean(false);
11+
812
private long id;
913

1014
public WebRtcMediator(long id) {
1115
this.id = id;
1216
}
1317

1418
public void act() {
15-
try (WebRtcMessagingClient client = new WebRtcMessagingClient(id);
16-
WebRtcWebSocketClient socketClient = new WebRtcWebSocketClient(client.getMessageHandler())) {
17-
client.setWebSocketClient(socketClient);
18-
} catch (Exception e) {
19-
logger.error(e);
19+
if (running.get()) {
20+
logger.warn("WebSocket and WebRTC peer connection(s) are already active with id {}", id);
21+
} else {
22+
running.set(true);
23+
try (WebRtcMessagingClient client = new WebRtcMessagingClient(id);
24+
WebRtcWebSocketClient socketClient = new WebRtcWebSocketClient(client.getMessageHandler())) {
25+
client.setWebSocketClient(socketClient);
26+
} catch (Exception e) {
27+
running.set(false);
28+
logger.error(e);
29+
}
2030
}
2131
}
2232
}

src/main/java/com/example/webrtc/WebRtcMessagingClient.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.example.webrtc;
22

3-
public class WebRtcMessagingClient implements AutoCloseable{
3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
45

6+
public class WebRtcMessagingClient implements AutoCloseable {
7+
private static final Logger logger = LogManager.getLogger(WebRtcMessagingClient.class);
58
private final WebRtcMessagingHandler messageHandler;
69

710
public WebRtcMessagingClient(long id) {
@@ -10,11 +13,11 @@ public WebRtcMessagingClient(long id) {
1013

1114
@Override
1215
public void close() throws Exception {
13-
throw new UnsupportedOperationException("Unimplemented method 'close'");
16+
logger.info("Closing WebRtcMessaging client");
1417
}
1518

1619
public WebRtcMessagingHandler getMessageHandler() {
17-
return messageHandler ;
20+
return messageHandler;
1821
}
1922

2023
public void setWebSocketClient(WebRtcWebSocketClient socketClient) {

0 commit comments

Comments
 (0)