Convert to and use LiveClientStopType enum for disconnecting websocket from magic numbers!

This commit is contained in:
kohlerpop1
2025-09-16 21:19:44 -04:00
parent 19ed45e6de
commit 03180d6a1c
7 changed files with 65 additions and 22 deletions

View File

@@ -24,6 +24,7 @@ package io.github.jwdeveloper.tiktok.live;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.listener.ListenersManager; import io.github.jwdeveloper.tiktok.listener.ListenersManager;
import io.github.jwdeveloper.tiktok.websocket.LiveClientStopType;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -49,16 +50,16 @@ public interface LiveClient {
/** /**
* Disconnects the connection. * Disconnects the connection.
* @param type * @param type {@code LiveClientStopType}
* <p>0 - Normal - Initiates disconnection and returns * @see LiveClientStopType
* <p>1 - Disconnects blocking and returns after closure
* <p>2 - Disconnects and kills connection to websocket
* <p>Default {@link #disconnect()} is 0
*/ */
void disconnect(int type); void disconnect(LiveClientStopType type);
/**
* Disconnects with {@link LiveClientStopType#NORMAL}
*/
default void disconnect() { default void disconnect() {
disconnect(0); disconnect(LiveClientStopType.NORMAL);
} }
/** /**

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023-2024 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.jwdeveloper.tiktok.websocket;
public enum LiveClientStopType
{
/**
* Initiates the websocket close handshake. This method does not block<br> In oder to make sure
* the connection is closed use {@link LiveClientStopType#CLOSE_BLOCKING}
*/
NORMAL,
/**
* Same as {@link LiveClientStopType#NORMAL} but blocks until the websocket closed or failed to do so.<br>
*
* @apiNote Can throw {@link InterruptedException} when/if the threads get interrupted
*/
CLOSE_BLOCKING,
/**
* This will close the connection immediately without a proper close handshake.
* The code and the message therefore won't be transferred over the wire also they will be forwarded to onClose/onWebsocketClose. */
DISCONNECT
}

View File

@@ -27,6 +27,6 @@ import io.github.jwdeveloper.tiktok.live.LiveClient;
public interface LiveSocketClient { public interface LiveSocketClient {
void start(LiveConnectionData.Response webcastResponse, LiveClient tikTokLiveClient); void start(LiveConnectionData.Response webcastResponse, LiveClient tikTokLiveClient);
void stop(int type); void stop(LiveClientStopType type);
boolean isConnected(); boolean isConnected();
} }

View File

@@ -35,7 +35,7 @@ import io.github.jwdeveloper.tiktok.listener.ListenersManager;
import io.github.jwdeveloper.tiktok.live.*; import io.github.jwdeveloper.tiktok.live.*;
import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult; import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult;
import io.github.jwdeveloper.tiktok.models.ConnectionState; import io.github.jwdeveloper.tiktok.models.ConnectionState;
import io.github.jwdeveloper.tiktok.websocket.LiveSocketClient; import io.github.jwdeveloper.tiktok.websocket.*;
import lombok.Getter; import lombok.Getter;
import java.util.Base64; import java.util.Base64;
@@ -166,7 +166,7 @@ public class TikTokLiveClient implements LiveClient
tikTokEventHandler.publish(this, new TikTokRoomInfoEvent(roomInfo)); tikTokEventHandler.publish(this, new TikTokRoomInfoEvent(roomInfo));
} }
public void disconnect(int type) { public void disconnect(LiveClientStopType type) {
if (webSocketClient.isConnected()) if (webSocketClient.isConnected())
webSocketClient.stop(type); webSocketClient.stop(type);
if (!roomInfo.hasConnectionState(ConnectionState.DISCONNECTED)) if (!roomInfo.hasConnectionState(ConnectionState.DISCONNECTED))

View File

@@ -57,7 +57,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
@Override @Override
public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) { public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) {
if (isConnected()) if (isConnected())
stop(0); stop(LiveClientStopType.NORMAL);
messageHandler.handle(liveClient, connectionData.getWebcastResponse()); messageHandler.handle(liveClient, connectionData.getWebcastResponse());
@@ -129,17 +129,17 @@ public class TikTokWebSocketClient implements LiveSocketClient {
} }
} }
public void stop(int type) { public void stop(LiveClientStopType type) {
if (isConnected()) { if (isConnected()) {
switch (type) { switch (type) {
case 1 -> { case CLOSE_BLOCKING -> {
try { try {
webSocketClient.closeBlocking(); webSocketClient.closeBlocking();
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new TikTokLiveException("Failed to stop the websocket"); throw new TikTokLiveException("Failed to stop the websocket");
} }
} }
case 2 -> webSocketClient.closeConnection(CloseFrame.NORMAL, ""); case DISCONNECT -> webSocketClient.closeConnection(CloseFrame.NORMAL, "");
default -> webSocketClient.close(); default -> webSocketClient.close();
} }
heartbeatTask.stop(webSocketClient); heartbeatTask.stop(webSocketClient);

View File

@@ -44,7 +44,7 @@ public class TikTokWebSocketOfflineClient implements LiveSocketClient {
} }
@Override @Override
public void stop(int type) { public void stop(LiveClientStopType type) {
if (liveClient != null) if (liveClient != null)
handler.publish(liveClient, new TikTokDisconnectedEvent("Stopping")); handler.publish(liveClient, new TikTokDisconnectedEvent("Stopping"));
} }

View File

@@ -23,14 +23,14 @@
package io.github.jwdeveloper.tiktok.websocket.euler; package io.github.jwdeveloper.tiktok.websocket.euler;
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData; import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
import io.github.jwdeveloper.tiktok.data.settings.*; import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
import io.github.jwdeveloper.tiktok.exceptions.*; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.live.*; import io.github.jwdeveloper.tiktok.live.*;
import io.github.jwdeveloper.tiktok.websocket.*; import io.github.jwdeveloper.tiktok.websocket.*;
import org.java_websocket.client.WebSocketClient; import org.java_websocket.client.WebSocketClient;
import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.CloseFrame;
import java.net.*; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
public class TikTokWebSocketEulerClient implements LiveSocketClient { public class TikTokWebSocketEulerClient implements LiveSocketClient {
@@ -53,7 +53,7 @@ public class TikTokWebSocketEulerClient implements LiveSocketClient {
@Override @Override
public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) { public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) {
if (isConnected()) if (isConnected())
stop(0); stop(LiveClientStopType.NORMAL);
webSocketClient = new TikTokWebSocketEulerListener( webSocketClient = new TikTokWebSocketEulerListener(
URI.create("wss://ws.eulerstream.com?uniqueId=%s&apiKey=%s&features.rawMessages=true".formatted(liveClient.getRoomInfo().getHostName(), clientSettings.getApiKey())), URI.create("wss://ws.eulerstream.com?uniqueId=%s&apiKey=%s&features.rawMessages=true".formatted(liveClient.getRoomInfo().getHostName(), clientSettings.getApiKey())),
@@ -74,17 +74,17 @@ public class TikTokWebSocketEulerClient implements LiveSocketClient {
} }
} }
public void stop(int type) { public void stop(LiveClientStopType type) {
if (isConnected()) { if (isConnected()) {
switch (type) { switch (type) {
case 1 -> { case CLOSE_BLOCKING -> {
try { try {
webSocketClient.closeBlocking(); webSocketClient.closeBlocking();
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new TikTokLiveException("Failed to stop the websocket"); throw new TikTokLiveException("Failed to stop the websocket");
} }
} }
case 2 -> webSocketClient.closeConnection(CloseFrame.NORMAL, ""); case DISCONNECT -> webSocketClient.closeConnection(CloseFrame.NORMAL, "");
default -> webSocketClient.close(); default -> webSocketClient.close();
} }
} }