Skip to content

Event lifetime

Jacek W edited this page Dec 11, 2023 · 6 revisions

In this articule you will learn how does TikTok data is translated into events

TikTokWebSocketListener

Initialy library runs webosocket client that listen for incoming data from tiktok. Data is coming in the binary format.

 @Override
    public void onMessage(ByteBuffer bytes)
    {
        try {
            handleBinary(bytes.array());
        } catch (Exception e) {
            tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(e));
        }
        if(isNotClosing())
        {
            sendPing();
        }
    }
 private void handleBinary(byte[] buffer) {
        var websocketMessageOptional = getWebcastWebsocketMessage(buffer);
        if (websocketMessageOptional.isEmpty()) {
            return;
        }
        var websocketMessage = websocketMessageOptional.get();
        var webResponse = getWebResponseMessage(websocketMessage.getPayload());

        if(webResponse.getNeedsAck())
        {
            //For some reason while send ack id, server get disconnected
           // sendAckId(webResponse.getFetchInterval());
        }

        webResponseHandler.handle(tikTokLiveClient, webResponse);
    }

WebcastPushFrame

First step is to parse binary to WebcastPushFrame class. This class contains most rudamenday data such as Timestand, payload, header, sesionId

   private Optional<WebcastPushFrame> getWebcastWebsocketMessage(byte[] buffer) {
        try {
            var websocketMessage = WebcastPushFrame.parseFrom(buffer);
            if (websocketMessage.getPayload().isEmpty()) {
                return Optional.empty();
            }
            return Optional.of(websocketMessage);
        } catch (Exception e) {
            throw new TikTokProtocolBufferException("Unable to parse WebcastPushFrame", buffer, e);
        }

WebcastResponse

Next we are parsing WebcastPushFrame.Payload to WebcastResponse. WebcastResponse give use way more data, but the most important one is WebcastResponse.getMessagesList(). It is lists of messages "events" that tiktok is sending to us.

   private WebcastResponse getWebResponseMessage(ByteString buffer) {
        try {
            return WebcastResponse.parseFrom(buffer);
        } catch (Exception e) {
            throw new TikTokProtocolBufferException("Unable to parse WebcastResponse", buffer.toByteArray(), e);
        }
    }

That's it for the websocket part, we now have WebcastResponse that is then processed in the TikTokMessageHandler

TikTokMessageHandler

This class is responsible from manage WebcastResponse and map events from tiktok to TikTokLiveJava events It gets all messages from WebcastResponse object and then map then one by one

worth to mention, before mapping TikTokWebsocketResponseEvent is triggered, that contains WebcastResponse object

   public void handle(LiveClient client, WebcastResponse webcastResponse) {
        tikTokEventHandler.publish(client, new TikTokWebsocketResponseEvent(webcastResponse));
        for (var message : webcastResponse.getMessagesList()) {
            try {
                handleSingleMessage(client, message);
            } catch (Exception e) {
                var exception = new TikTokLiveMessageException(message, webcastResponse, e);
                tikTokEventHandler.publish(client, new TikTokErrorEvent(exception));
            }
        }
    }

Each message is processed by method handleSingleMessage

public void handleSingleMessage(LiveClient client, WebcastResponse.Message message) throws Exception {
        var messageClassName = message.getMethod(); //getting message name, for example WebcastGiftEvent
        if (!handlers.containsKey(messageClassName)) {  //checking if mapping handler was registered for message name
            tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message)); //if there is no handler, fire TikTokWebsocketUnhandledMessageEvent
            return;
        }
        var handler = handlers.get(messageClassName); //getitng handler
        var stopwatch = new Stopwatch();
        stopwatch.start();     
        var events = handler.handle(message.getPayload().toByteArray()); //handle mapping
        var handlingTimeInMs = stopwatch.stop();
        var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs)); //creating mapping metdataobject

        for (var event : events) {   //mapping handler might map TikTok message to more then one events, thats way there is a list
            tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata)); // for every mapped message there is triggered TikTokWebsocketMessageEvent 
            tikTokEventHandler.publish(client, event); //fire actual event, for example WebcastGiftMessage, was mapped to TikTokGiftEvent
        }
    }
Clone this wiki locally