Skip to content

Commit 59f55ed

Browse files
committed
Added websocket error callback; prevent end-user defined callbacks from blocking websocket code execution; added connect/disconnect methods accessible by end-user;
1 parent 92a3ffb commit 59f55ed

File tree

11 files changed

+582
-146
lines changed

11 files changed

+582
-146
lines changed

src/main/java/net/twasi/obsremotejava/OBSCommunicator.java

Lines changed: 184 additions & 92 deletions
Large diffs are not rendered by default.

src/main/java/net/twasi/obsremotejava/OBSRemoteController.java

Lines changed: 105 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package net.twasi.obsremotejava;
22

3-
import net.twasi.obsremotejava.requests.ResponseBase;
3+
import net.twasi.obsremotejava.callbacks.Callback;
4+
import net.twasi.obsremotejava.callbacks.ErrorCallback;
5+
import net.twasi.obsremotejava.callbacks.StringCallback;
6+
import net.twasi.obsremotejava.objects.throwables.OBSResponseError;
47
import org.eclipse.jetty.websocket.api.Session;
58
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
69
import org.eclipse.jetty.websocket.client.WebSocketClient;
@@ -10,70 +13,116 @@
1013
import java.util.Map;
1114
import java.util.concurrent.ExecutionException;
1215
import java.util.concurrent.Future;
16+
import java.util.concurrent.TimeUnit;
1317

1418
public class OBSRemoteController {
1519
private String address;
16-
private OBSCommunicator communicator;
17-
private WebSocketClient client;
20+
private final boolean debug;
21+
private final OBSCommunicator communicator;
22+
private final String password;
23+
private final WebSocketClient client;
24+
25+
private StringCallback onConnectionFailed;
26+
private ErrorCallback onError;
1827

1928
private boolean failed;
2029

21-
public OBSRemoteController(String address, boolean debug, String password) {
30+
public OBSRemoteController(String address, boolean debug, String password, boolean autoConnect) {
2231
this.address = address;
23-
communicator = new OBSCommunicator(debug, password);
32+
this.debug = debug;
33+
this.password = password;
34+
2435
client = new WebSocketClient();
36+
communicator = new OBSCommunicator(debug, password);
37+
38+
if (autoConnect) {
39+
connect();
40+
}
41+
}
42+
43+
public OBSRemoteController(String address, boolean debug, String password) {
44+
this(address, debug, password, true);
45+
}
46+
47+
public OBSRemoteController(String address, boolean debug) {
48+
this(address, debug, null);
49+
}
50+
51+
public void connect() {
2552
try {
2653
client.start();
54+
} catch (Exception e) {
55+
System.err.println("Failed to start WebSocketClient.");
56+
e.printStackTrace();
57+
runOnError("Failed to start WebSocketClient", e);
58+
return;
59+
}
2760

61+
try {
2862
URI uri = new URI(address);
2963
ClientUpgradeRequest request = new ClientUpgradeRequest();
3064
Future<Session> connection = client.connect(communicator, uri, request);
31-
System.out.printf("Connecting to: %s%s%n", uri, (password != null ? " with password" : ""));
65+
System.out.printf("Connecting to: %s%s.%n", uri, (password != null ? " with password" : ""));
3266

3367
try {
3468
connection.get();
3569
failed = false;
3670
} catch (ExecutionException e) {
3771
if (e.getCause() instanceof ConnectException) {
38-
System.out.println("Connection to OBS failed.");
72+
System.out.println("Failed to connect to OBS.");
73+
e.printStackTrace();
74+
3975
failed = true;
40-
}
41-
}
4276

43-
/* new Thread() {
44-
@Override
45-
public void run() {
46-
try {
47-
communicator.await();
48-
} catch (InterruptedException e) {
49-
e.printStackTrace();
50-
}
77+
runOnConnectionFailed("Failed to connect to OBS");
78+
} else {
79+
throw e;
5180
}
52-
}.start(); */
53-
//communicator.;
54-
81+
}
5582
} catch (Throwable t) {
83+
System.err.println("Failed to setup connection with OBS.");
5684
t.printStackTrace();
57-
} finally {
85+
runOnConnectionFailed("Failed to setup connection with OBS");
86+
}
87+
}
88+
89+
public void disconnect() {
90+
// wait for closed socket connection
91+
try {
92+
if (debug) {
93+
System.out.println("Closing connection.");
94+
}
95+
communicator.awaitClose(1, TimeUnit.SECONDS);
96+
} catch (InterruptedException e) {
97+
e.printStackTrace();
98+
runOnError("Error during closing websocket connection", e);
99+
}
100+
101+
if (!client.isStopped() && !client.isStopping()) {
58102
try {
59-
//client.stop();
103+
if (debug) {
104+
System.out.println("Stopping client.");
105+
}
106+
client.stop();
60107
} catch (Exception e) {
61108
e.printStackTrace();
109+
runOnError("Error during stopping websocket client", e);
62110
}
63111
}
64112
}
65113

66-
public OBSRemoteController(String address, boolean debug) {
67-
this(address, debug, null);
68-
}
69-
70114
public boolean isFailed() {
71115
return failed;
72116
}
73117

74118
public void getScenes(Callback callback) {
75119
communicator.getScenes(callback);
76-
};
120+
}
121+
122+
public void registerOnError(ErrorCallback onError) {
123+
this.onError = onError;
124+
communicator.registerOnError(onError);
125+
}
77126

78127
public void registerConnectCallback(Callback onConnect) {
79128
communicator.registerOnConnect(onConnect);
@@ -84,6 +133,7 @@ public void registerDisconnectCallback(Callback onDisconnect) {
84133
}
85134

86135
public void registerConnectionFailedCallback(StringCallback onConnectionFailed) {
136+
this.onConnectionFailed = onConnectionFailed;
87137
communicator.registerOnConnectionFailed(onConnectionFailed);
88138
}
89139

@@ -132,14 +182,12 @@ public void setCurrentTransition(String transition, Callback callback) {
132182
}
133183

134184
public void changeSceneWithTransition(final String scene, String transition, final Callback callback) {
135-
communicator.setCurrentTransition(transition, new Callback() {
136-
@Override
137-
public void run(ResponseBase response) {
138-
if (!response.getStatus().equals("ok")) {
139-
System.out.println("Failed to change transition. Pls fix.");
140-
}
141-
communicator.setCurrentScene(scene, callback);
185+
communicator.setCurrentTransition(transition, response -> {
186+
if (!response.getStatus().equals("ok")) {
187+
System.out.println("Failed to change transition. Pls fix.");
188+
runOnError("Error response for changeSceneWithTransition", new OBSResponseError(response.getError()));
142189
}
190+
communicator.setCurrentScene(scene, callback);
143191
});
144192
}
145193

@@ -244,4 +292,27 @@ public void saveReplayBuffer(Callback callback) {
244292
communicator.saveReplayBuffer(callback);
245293
}
246294

295+
private void runOnError(String message, Throwable throwable) {
296+
if (onError == null) {
297+
return;
298+
}
299+
300+
try {
301+
onError.run(message, throwable);
302+
} catch (Exception e) {
303+
e.printStackTrace();
304+
}
305+
}
306+
307+
private void runOnConnectionFailed(String message) {
308+
if (onConnectionFailed == null) {
309+
return;
310+
}
311+
312+
try {
313+
onConnectionFailed.run(message);
314+
} catch (Exception e) {
315+
e.printStackTrace();
316+
}
317+
}
247318
}

src/main/java/net/twasi/obsremotejava/Callback.java renamed to src/main/java/net/twasi/obsremotejava/callbacks/Callback.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.twasi.obsremotejava;
1+
package net.twasi.obsremotejava.callbacks;
22

33
import net.twasi.obsremotejava.requests.ResponseBase;
44

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.twasi.obsremotejava.callbacks;
2+
3+
public interface ErrorCallback {
4+
void run(String message, Throwable throwable);
5+
}

src/main/java/net/twasi/obsremotejava/StringCallback.java renamed to src/main/java/net/twasi/obsremotejava/callbacks/StringCallback.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.twasi.obsremotejava;
1+
package net.twasi.obsremotejava.callbacks;
22

33
public interface StringCallback {
44
void run(String message);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.twasi.obsremotejava.objects.throwables;
2+
3+
import javax.management.openmbean.InvalidKeyException;
4+
5+
public class InvalidResponseTypeError extends InvalidKeyException {
6+
public InvalidResponseTypeError(String s) {
7+
super(s);
8+
}
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.twasi.obsremotejava.objects.throwables;
2+
3+
public class OBSResponseError extends Error {
4+
public OBSResponseError(String s) {
5+
super(s);
6+
}
7+
}

src/test/java/net/twasi/obsremotejava/test/OBSCommunicatorTest.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,20 @@
1111
import java.util.concurrent.TimeUnit;
1212
import java.util.concurrent.atomic.AtomicReference;
1313

14-
import static org.junit.jupiter.api.Assertions.assertEquals;
15-
import static org.junit.jupiter.api.Assertions.fail;
14+
import static org.junit.jupiter.api.Assertions.*;
1615

1716
/**
1817
* Read comment instructions before each test
1918
*/
2019
class OBSCommunicatorTest {
2120

21+
/**
22+
* - Set these two values before running these tests
23+
* - Make sure your OBS is running and available for connection
24+
*/
25+
private final String obsAddress = "ws://localhost:4444";
26+
private final String obsPassword = "password";
27+
2228
/**
2329
* Before running this test:
2430
* - Start OBS locally
@@ -27,8 +33,6 @@ class OBSCommunicatorTest {
2733
*/
2834
@Test
2935
void testConnectToUnsecureServerWithoutPassword() throws Exception {
30-
String destUri = "ws://localhost:4444";
31-
3236
WebSocketClient client = new WebSocketClient();
3337
OBSCommunicator connector = new OBSCommunicator(true);
3438

@@ -37,7 +41,7 @@ void testConnectToUnsecureServerWithoutPassword() throws Exception {
3741
try {
3842
client.start();
3943

40-
URI echoUri = new URI(destUri);
44+
URI echoUri = new URI(obsAddress);
4145
ClientUpgradeRequest request = new ClientUpgradeRequest();
4246
client.connect(connector, echoUri, request);
4347
System.out.printf("Connecting to : %s%n", echoUri);
@@ -73,7 +77,6 @@ void testConnectToUnsecureServerWithoutPassword() throws Exception {
7377
*/
7478
@Test
7579
void testConnectToSecuredServerWithoutPassword() throws Exception {
76-
String destUri = "ws://localhost:4444";
7780
String websocketPassword = null;
7881

7982
WebSocketClient client = new WebSocketClient();
@@ -85,7 +88,7 @@ void testConnectToSecuredServerWithoutPassword() throws Exception {
8588
try {
8689
client.start();
8790

88-
URI echoUri = new URI(destUri);
91+
URI echoUri = new URI(obsAddress);
8992
ClientUpgradeRequest request = new ClientUpgradeRequest();
9093
Future<Session> connection = client.connect(connector, echoUri, request);
9194
System.out.printf("Connecting to : %s%n", echoUri);
@@ -114,21 +117,19 @@ void testConnectToSecuredServerWithoutPassword() throws Exception {
114117
fail(testFailedReason.get());
115118
}
116119

117-
assertEquals("Authentication required by server but no password set for client",
120+
assertEquals("Authentication required by server but no password set by client",
118121
connectionFailedResult.get());
119122
}
120123

121124
/**
122125
* Before running this test:
123126
* - Start OBS locally
124127
* - Enable websocket authentication
125-
* - Make sure websocket password doesn't match websocketPassword below
126128
* - Run test
127129
*/
128130
@Test
129131
void testConnectToSecuredServerWithInCorrectPassword() throws Exception {
130-
String destUri = "ws://localhost:4444";
131-
String websocketPassword = "this-is-an-incorrect-password";
132+
String websocketPassword = obsPassword + "giberish";
132133

133134
WebSocketClient client = new WebSocketClient();
134135
OBSCommunicator connector = new OBSCommunicator(true, websocketPassword);
@@ -139,7 +140,7 @@ void testConnectToSecuredServerWithInCorrectPassword() throws Exception {
139140
try {
140141
client.start();
141142

142-
URI echoUri = new URI(destUri);
143+
URI echoUri = new URI(obsAddress);
143144
ClientUpgradeRequest request = new ClientUpgradeRequest();
144145
Future<Session> connection = client.connect(connector, echoUri, request);
145146
System.out.printf("Connecting to : %s%n", echoUri);
@@ -176,13 +177,12 @@ void testConnectToSecuredServerWithInCorrectPassword() throws Exception {
176177
* Before running this test:
177178
* - Start OBS locally
178179
* - Enable websocket authentication
179-
* - Set websocket password to "password" or edit websocketPassword below to correct password
180+
* - Set obsPassword to your OBS websocket's password
180181
* - Run test
181182
*/
182183
@Test
183184
void testConnectToSecuredServerWithCorrectPassword() throws Exception {
184-
String destUri = "ws://localhost:4444";
185-
String websocketPassword = "password";
185+
String websocketPassword = obsPassword;
186186

187187
WebSocketClient client = new WebSocketClient();
188188
OBSCommunicator connector = new OBSCommunicator(true, websocketPassword);
@@ -192,7 +192,7 @@ void testConnectToSecuredServerWithCorrectPassword() throws Exception {
192192
try {
193193
client.start();
194194

195-
URI echoUri = new URI(destUri);
195+
URI echoUri = new URI(obsAddress);
196196
ClientUpgradeRequest request = new ClientUpgradeRequest();
197197
Future<Session> connection = client.connect(connector, echoUri, request);
198198
System.out.printf("Connecting to : %s%n", echoUri);

0 commit comments

Comments
 (0)