Improve error handling and set timeouts in the Cam4 websocket

This commit is contained in:
0xb00bface 2020-12-19 17:41:44 +01:00
parent 3d076cdde6
commit a3ffa7a71e
2 changed files with 24 additions and 7 deletions

View File

@ -87,9 +87,13 @@ public class Cam4Model extends AbstractModel {
case "INSIDE_PS":
onlineState = PRIVATE;
break;
case "INSIDE_GS":
case "GROUP_SHOW":
onlineState = GROUP;
break;
case "PAUSED":
onlineState = AWAY;
break;
case "OFFLINE":
onlineState = OFFLINE;
break;

View File

@ -2,6 +2,7 @@ package ctbrec.sites.cam4;
import static ctbrec.io.HttpConstants.*;
import java.io.EOFException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -34,7 +35,8 @@ public class Cam4WsClient {
private String token;
private WebSocket websocket;
private int r = 1;
private Map<String, CompletableFuture<String>> responseFutures = new HashMap<>();
private Map<String, CompletableFuture<String>> responseFuturesByPath = new HashMap<>();
private Map<Integer, CompletableFuture<String>> responseFuturesBySequence = new HashMap<>();
public Cam4WsClient(Config config, Cam4 site, Cam4Model model) {
this.config = config;
@ -55,7 +57,7 @@ public class Cam4WsClient {
String p = "chatRooms/" + model.getName() + "/roomState";
CompletableFuture<String> roomStateFuture = send(p, "{\"t\":\"d\",\"d\":{\"r\":" + (r++) + ",\"a\":\"q\",\"b\":{\"p\":\"" + p + "\",\"h\":\"\"}}}");
try {
JSONObject roomState = parseRoomStateResponse(roomStateFuture.get(5000, TimeUnit.SECONDS));
JSONObject roomState = parseRoomStateResponse(roomStateFuture.get(1, TimeUnit.SECONDS));
websocket.close(1000, "");
return roomState;
} catch (InterruptedException e) {
@ -69,7 +71,7 @@ public class Cam4WsClient {
private boolean connectAndAuthorize() throws IOException {
CompletableFuture<Boolean> connectedAndAuthorized = openWebsocketConnection();
try {
return connectedAndAuthorized.get(5000, TimeUnit.SECONDS);
return connectedAndAuthorized.get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted while connecting with websocket");
@ -85,7 +87,7 @@ public class Cam4WsClient {
if (!sent) {
future.completeExceptionally(new IOException("send() returned false"));
} else {
responseFutures.put(p, future);
responseFuturesByPath.put(p, future);
}
return future;
}
@ -157,6 +159,9 @@ public class Cam4WsClient {
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
super.onFailure(webSocket, t, response);
try {
if (t instanceof EOFException) {
return;
}
if(response != null) {
LOG.error("failure {}: {}", model, response.body().string(), t);
} else {
@ -164,8 +169,9 @@ public class Cam4WsClient {
}
} catch (IOException e) {
LOG.error("Connection failure and couldn't get the response body", e);
} finally {
connectedAndAuthorized.completeExceptionally(t);
}
connectedAndAuthorized.completeExceptionally(t);
}
@Override
@ -180,11 +186,18 @@ public class Cam4WsClient {
JSONObject body = d.getJSONObject("b");
String status = body.optString("s");
connectedAndAuthorized.complete(status.equals("ok"));
} else if (responseFuturesBySequence.containsKey(responseSequence)) {
JSONObject body = d.getJSONObject("b");
String status = body.optString("s");
if (!status.equals("ok")) {
CompletableFuture<String> future = responseFuturesBySequence.remove(responseSequence);
future.completeExceptionally(new IOException(status));
}
} else if (d.has("b")) {
JSONObject body = d.getJSONObject("b");
String p = body.optString("p", "-");
if (responseFutures.containsKey(p)) {
CompletableFuture<String> future = responseFutures.get(p);
if (responseFuturesByPath.containsKey(p)) {
CompletableFuture<String> future = responseFuturesByPath.remove(p);
future.complete(text);
}
}