Improve addProxy(String addressPort) in ProxyClientSettings

Added @param action description and return values
Optimized methods in TikTokLiveMapper
Optimized Thread in TikTokWebSocketPingingTask
Optimized TikTokLiveEventHandler and TikTokLiveMessageHandler methods
This commit is contained in:
kohlerpop1
2024-06-29 23:28:49 -04:00
parent f2bd07377b
commit 947c9c49a2
7 changed files with 71 additions and 120 deletions

View File

@@ -41,7 +41,7 @@ public class ProxyClientSettings implements Iterator<ProxyData>, Iterable<ProxyD
private Consumer<ProxyData> onProxyUpdated = x -> {}; private Consumer<ProxyData> onProxyUpdated = x -> {};
public boolean addProxy(String addressPort) { public boolean addProxy(String addressPort) {
return proxyList.add(ProxyData.map(addressPort)); return addProxy(ProxyData.map(addressPort).toSocketAddress());
} }
public boolean addProxy(String address, int port) { public boolean addProxy(String address, int port) {
@@ -117,7 +117,7 @@ public class ProxyClientSettings implements Iterator<ProxyData>, Iterable<ProxyD
} }
/** /**
* With Iterable<?> interface you can use this object inside For loop! * With {@code Iterable<ProxyData>} interface, you can use this object inside for loop!
*/ */
@Override @Override
public Iterator<ProxyData> iterator() { public Iterator<ProxyData> iterator() {

View File

@@ -52,77 +52,70 @@ public interface EventsBuilder<T> {
/** /**
* Invoked whenever any event is triggered * Invoked whenever any event is triggered
* *
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onEvent(EventConsumer<TikTokEvent> action); T onEvent(EventConsumer<TikTokEvent> action);
/** /**
* Invoked when information about room (live) got updated such as viewer count, etc.. * Invoked when information about room (live) got updated such as viewer count, etc..
* *
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onRoomInfo(EventConsumer<TikTokRoomInfoEvent> action); T onRoomInfo(EventConsumer<TikTokRoomInfoEvent> action);
/** /**
* Invoked when someone send message to chat * Invoked when someone send message to chat
* * @param action consumable action
* @param action * @return self instance
* @return
*/ */
T onComment(EventConsumer<TikTokCommentEvent> action); T onComment(EventConsumer<TikTokCommentEvent> action);
/** /**
* Invoked when TikTokLiveJava makes http request and getting response * Invoked when TikTokLiveJava makes http request and getting response
* * @param action consumable action
* @param action * @return self instance
* @return
*/ */
T onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action); T onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action);
/** /**
* Invoked when TikTok protocolBuffer data "message" was successfully mapped to event * Invoked when TikTok protocolBuffer data "message" was successfully mapped to event
* events contains protocol-buffer "Message" and TikTokLiveJava "Event" * events contains protocol-buffer "Message" and TikTokLiveJava "Event"
* * @param action consumable action
* @param action * @return self instance
* @return
*/ */
T onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> action); T onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> action);
/** /**
* Invoked when there was not found event mapper for TikTok protocolBuffer data "message" * Invoked when there was not found event mapper for TikTok protocolBuffer data "message"
* * @param action consumable action
* @param action * @return self instance
* @return
*/ */
T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> action); T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> action);
/** /**
* Invoked every time TikTok sends protocolBuffer data to websocket * Invoked every time TikTok sends protocolBuffer data to websocket
* Response contains list of messages that are later mapped to events * Response contains list of messages that are later mapped to events
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> action); T onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> action);
/** /**
* Invoked for gifts that has no combo, or when combo finishes * Invoked for gifts that has no combo, or when combo finishes
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onGift(EventConsumer<TikTokGiftEvent> action); T onGift(EventConsumer<TikTokGiftEvent> action);
/** /**
* Invoked for gifts that has combo options such as roses * Invoked for gifts that has combo options such as roses
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action); T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action);
T onQuestion(EventConsumer<TikTokQuestionEvent> action); T onQuestion(EventConsumer<TikTokQuestionEvent> action);
T onSubscribe(EventConsumer<TikTokSubscribeEvent> action); T onSubscribe(EventConsumer<TikTokSubscribeEvent> action);
@@ -145,36 +138,36 @@ public interface EventsBuilder<T> {
/** /**
* Invoked when client has been successfully connected to live * Invoked when client has been successfully connected to live
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onConnected(EventConsumer<TikTokConnectedEvent> action); T onConnected(EventConsumer<TikTokConnectedEvent> action);
/** /**
* Invoked before client has been successfully connected to live * Invoked before client has been successfully connected to live
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onPreConnection(EventConsumer<TikTokPreConnectionEvent> action); T onPreConnection(EventConsumer<TikTokPreConnectionEvent> action);
/** /**
* Invoked when client tries to reconnect * Invoked when client tries to reconnect
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onReconnecting(EventConsumer<TikTokReconnectingEvent> action); T onReconnecting(EventConsumer<TikTokReconnectingEvent> action);
/** /**
* Invoked when client disconnected * Invoked when client disconnected
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onDisconnected(EventConsumer<TikTokDisconnectedEvent> action); T onDisconnected(EventConsumer<TikTokDisconnectedEvent> action);
/** /**
* Invoked when exception was throed inside client or event handler * Invoked when exception was throed inside client or event handler
* @param action * @param action consumable action
* @return * @return self instance
*/ */
T onError(EventConsumer<TikTokErrorEvent> action); T onError(EventConsumer<TikTokErrorEvent> action);

View File

@@ -148,11 +148,11 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpClient.class); dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpClient.class);
} }
/** TODO in future, custom proxy implementation that can be provided via builder /* TODO in future, custom proxy implementation that can be provided via builder
* if(customProxy != null) * if(customProxy != null)
* dependance.registerSingleton(TikTokProxyProvider.class,customProxy); * dependance.registerSingleton(TikTokProxyProvider.class,customProxy);
* else * else
* dependance.registerSingleton(TikTokProxyProvider.class,DefaultProxyProvider.class); * dependance.registerSingleton(TikTokProxyProvider.class,DefaultProxyProvider.class);
*/ */
//gifts //gifts

View File

@@ -26,10 +26,7 @@ import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer; import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;
import java.util.HashMap; import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class TikTokLiveEventHandler { public class TikTokLiveEventHandler {
private final Map<Class<?>, Set<EventConsumer>> events; private final Map<Class<?>, Set<EventConsumer>> events;
@@ -39,16 +36,8 @@ public class TikTokLiveEventHandler {
} }
public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) { public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) {
if (events.containsKey(TikTokEvent.class)) { Optional.ofNullable(events.get(TikTokEvent.class)).ifPresent(handlers -> handlers.forEach(handler -> handler.onEvent(tikTokLiveClient, tikTokEvent)));
var handlers = events.get(TikTokEvent.class); Optional.ofNullable(events.get(tikTokEvent.getClass())).ifPresent(handlers -> handlers.forEach(handler -> handler.onEvent(tikTokLiveClient, tikTokEvent)));
handlers.forEach(handler -> handler.onEvent(tikTokLiveClient,tikTokEvent));
}
if (!events.containsKey(tikTokEvent.getClass())) {
return;
}
var handlers = events.get(tikTokEvent.getClass());
handlers.forEach(handler -> handler.onEvent(tikTokLiveClient,tikTokEvent));
} }
public <T extends TikTokEvent> void subscribe(Class<?> clazz, EventConsumer<T> event) { public <T extends TikTokEvent> void subscribe(Class<?> clazz, EventConsumer<T> event) {
@@ -60,21 +49,11 @@ public class TikTokLiveEventHandler {
} }
public <T extends TikTokEvent> void unsubscribe(EventConsumer<T> consumer) { public <T extends TikTokEvent> void unsubscribe(EventConsumer<T> consumer) {
for (var entry : events.entrySet()) { events.forEach((key, value) -> value.remove(consumer));
entry.getValue().remove(consumer);
}
} }
public <T extends TikTokEvent> void unsubscribe(Class<?> clazz, EventConsumer<T> consumer) { public <T extends TikTokEvent> void unsubscribe(Class<?> clazz, EventConsumer<T> consumer) {
if (clazz == null) { if (clazz != null)
return; Optional.ofNullable(events.get(clazz)).ifPresent(eventConsumers -> eventConsumers.remove(consumer));
} }
}
if (!events.containsKey(clazz)) {
return;
}
var eventSet = events.get(clazz);
eventSet.remove(consumer);
}
}

View File

@@ -44,7 +44,7 @@ public class TikTokLiveMessageHandler {
public TikTokLiveMessageHandler(TikTokLiveEventHandler tikTokEventHandler, TikTokMapper mapper) { public TikTokLiveMessageHandler(TikTokLiveEventHandler tikTokEventHandler, TikTokMapper mapper) {
this.tikTokEventHandler = tikTokEventHandler; this.tikTokEventHandler = tikTokEventHandler;
this.mapper = (TikTokLiveMapper)mapper; this.mapper = (TikTokLiveMapper) mapper;
} }
public void handle(LiveClient client, WebcastResponse webcastResponse) { public void handle(LiveClient client, WebcastResponse webcastResponse) {
@@ -62,20 +62,19 @@ public class TikTokLiveMessageHandler {
public void handleSingleMessage(LiveClient client, WebcastResponse.Message message) public void handleSingleMessage(LiveClient client, WebcastResponse.Message message)
{ {
var messageClassName = message.getMethod(); var messageClassName = message.getMethod();
if (!mapper.isRegistered(messageClassName)) { if (!mapper.isRegistered(messageClassName))
tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message)); tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message));
return; else {
} var stopwatch = new Stopwatch();
var stopwatch = new Stopwatch(); stopwatch.start();
stopwatch.start(); var events = mapper.handleMapping(messageClassName, message.getPayload().toByteArray());
var events = mapper.handleMapping(messageClassName, message.getPayload().toByteArray()); var handlingTimeInMs = stopwatch.stop();
var handlingTimeInMs = stopwatch.stop(); var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs));
var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs));
for (var event : events) { for (var event : events) {
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata)); tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata));
tikTokEventHandler.publish(client, event); tikTokEventHandler.publish(client, event);
}
} }
} }
}
}

View File

@@ -23,14 +23,10 @@
package io.github.jwdeveloper.tiktok.mappers; package io.github.jwdeveloper.tiktok.mappers;
import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.GeneratedMessageV3;
import io.github.jwdeveloper.tiktok.TikTokLive;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.mappers.data.MappingAction; import io.github.jwdeveloper.tiktok.mappers.data.*;
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
public class TikTokLiveMapper implements TikTokMapper { public class TikTokLiveMapper implements TikTokMapper {
@@ -47,11 +43,7 @@ public class TikTokLiveMapper implements TikTokMapper {
@Override @Override
public TikTokMapperModel forMessage(String messageName) { public TikTokMapperModel forMessage(String messageName) {
if (!isRegistered(messageName)) { return mappers.computeIfAbsent(messageName, TikTokLiveMapperModel::new);
var model = new TikTokLiveMapperModel(messageName);
mappers.put(messageName, model);
}
return mappers.get(messageName);
} }
@Override @Override
@@ -66,7 +58,6 @@ public class TikTokLiveMapper implements TikTokMapper {
return model; return model;
} }
@Override @Override
public TikTokMapperModel forMessage(Class<? extends GeneratedMessageV3> mapperName, MappingAction<MappingResult> onMapping) { public TikTokMapperModel forMessage(Class<? extends GeneratedMessageV3> mapperName, MappingAction<MappingResult> onMapping) {
var model = forMessage(mapperName); var model = forMessage(mapperName);
@@ -84,7 +75,6 @@ public class TikTokLiveMapper implements TikTokMapper {
return globalMapperModel; return globalMapperModel;
} }
public boolean isRegistered(String mapperName) { public boolean isRegistered(String mapperName) {
return mappers.containsKey(mapperName); return mappers.containsKey(mapperName);
} }
@@ -94,23 +84,19 @@ public class TikTokLiveMapper implements TikTokMapper {
} }
public List<TikTokEvent> handleMapping(String messageName, byte[] bytes) { public List<TikTokEvent> handleMapping(String messageName, byte[] bytes) {
if (!isRegistered(messageName)) {
return List.of();
}
var mapperModel = mappers.get(messageName); var mapperModel = mappers.get(messageName);
if (mapperModel == null)
return List.of();
var inputBytes = mapperModel.getOnBeforeMapping().onMapping(bytes, messageName, mapperUtils); var inputBytes = mapperModel.getOnBeforeMapping().onMapping(bytes, messageName, mapperUtils);
var globalInputBytes = globalMapperModel.getOnBeforeMapping().onMapping(inputBytes, messageName, mapperUtils); var globalInputBytes = globalMapperModel.getOnBeforeMapping().onMapping(inputBytes, messageName, mapperUtils);
var mappingResult = mapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils); var mappingResult = mapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
if (mappingResult == null) { if (mappingResult == null)
mappingResult = globalMapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils); mappingResult = globalMapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
}
var afterMappingResult = mapperModel.getOnAfterMapping().apply(mappingResult); var afterMappingResult = mapperModel.getOnAfterMapping().apply(mappingResult);
var globalAfterMappingResult = globalMapperModel.getOnAfterMapping().apply(MappingResult.of(mappingResult.getSource(), afterMappingResult)); return globalMapperModel.getOnAfterMapping().apply(MappingResult.of(mappingResult.getSource(), afterMappingResult));
return globalAfterMappingResult;
} }
} }

View File

@@ -24,8 +24,6 @@ package io.github.jwdeveloper.tiktok.websocket;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
import java.util.Random;
public class TikTokWebSocketPingingTask public class TikTokWebSocketPingingTask
{ {
private Thread thread; private Thread thread;
@@ -36,8 +34,7 @@ public class TikTokWebSocketPingingTask
public void run(WebSocket webSocket, long pingTaskTime) public void run(WebSocket webSocket, long pingTaskTime)
{ {
stop(); stop();
thread = new Thread(() -> pingTask(webSocket, pingTaskTime)); thread = new Thread(() -> pingTask(webSocket, pingTaskTime), "pinging-task");
thread.setName("pinging-task");
isRunning = true; isRunning = true;
thread.start(); thread.start();
} }
@@ -51,16 +48,13 @@ public class TikTokWebSocketPingingTask
private void pingTask(WebSocket webSocket, long pingTaskTime) private void pingTask(WebSocket webSocket, long pingTaskTime)
{ {
var random = new Random();
while (isRunning) { while (isRunning) {
try { try {
if (!webSocket.isOpen()) { if (webSocket.isOpen()) {
webSocket.sendPing();
Thread.sleep(pingTaskTime+(int)(Math.random() * MAX_TIMEOUT));
} else
Thread.sleep(SLEEP_TIME); Thread.sleep(SLEEP_TIME);
continue;
}
webSocket.sendPing();
Thread.sleep(pingTaskTime+random.nextInt(MAX_TIMEOUT));
} }
catch (Exception e) { catch (Exception e) {
//TODO we should display some kind of error message //TODO we should display some kind of error message