All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.contek.invoker.okx.api.websocket.WebSocketChannel Maven / Gradle / Ivy

package io.contek.invoker.okx.api.websocket;

import com.google.common.collect.ImmutableList;
import io.contek.invoker.commons.websocket.AnyWebSocketMessage;
import io.contek.invoker.commons.websocket.BaseWebSocketChannel;
import io.contek.invoker.commons.websocket.SubscriptionState;
import io.contek.invoker.commons.websocket.WebSocketSession;
import io.contek.invoker.okx.api.websocket.common.WebSocketChannelArg;
import io.contek.invoker.okx.api.websocket.common.WebSocketChannelPushData;
import io.contek.invoker.okx.api.websocket.common.WebSocketSubscriptionRequest;
import io.contek.invoker.okx.api.websocket.common.WebSocketSubscriptionResponse;
import io.contek.invoker.okx.api.websocket.common.constants.WebSocketOutboundKeys;

import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import static io.contek.invoker.commons.websocket.SubscriptionState.*;
import static io.contek.invoker.okx.api.websocket.common.constants.WebSocketInboundKeys._subscribe;
import static io.contek.invoker.okx.api.websocket.common.constants.WebSocketInboundKeys._unsubscribe;

@ThreadSafe
public abstract class WebSocketChannel>
    extends BaseWebSocketChannel, Message, Message> {

  private final AtomicReference pendingRequestHolder =
      new AtomicReference<>(null);

  protected WebSocketChannel(WebSocketChannelId id) {
    super(id);
  }

  @Override
  protected Message getData(Message message) {
    return message;
  }

  @Override
  protected final SubscriptionState subscribe(WebSocketSession session) {
    synchronized (pendingRequestHolder) {
      if (pendingRequestHolder.get() != null) {
        throw new IllegalStateException();
      }

      WebSocketSubscriptionRequest request = new WebSocketSubscriptionRequest();
      request.op = WebSocketOutboundKeys._subscribe;
      request.args = ImmutableList.of(getId().toChannelArg());
      session.send(request);
      pendingRequestHolder.set(request);
    }
    return SUBSCRIBING;
  }

  @Override
  protected final SubscriptionState unsubscribe(WebSocketSession session) {
    synchronized (pendingRequestHolder) {
      if (pendingRequestHolder.get() != null) {
        throw new IllegalStateException();
      }

      WebSocketSubscriptionRequest request = new WebSocketSubscriptionRequest();
      request.op = WebSocketOutboundKeys._unsubscribe;
      request.args = ImmutableList.of(getId().toChannelArg());
      session.send(request);
      pendingRequestHolder.set(request);
    }
    return UNSUBSCRIBING;
  }

  @Nullable
  @Override
  protected final SubscriptionState getState(AnyWebSocketMessage message) {
    if (!(message instanceof WebSocketSubscriptionResponse response)) {
      return null;
    }

    synchronized (pendingRequestHolder) {
      WebSocketSubscriptionRequest request = pendingRequestHolder.get();
      if (request == null) {
        return null;
      }

      WebSocketChannelArg requestArg = request.args.get(0);
      WebSocketChannelArg responseArg = response.arg;
      if (!Objects.equals(requestArg.channel, responseArg.channel)
          || !Objects.equals(requestArg.instType, responseArg.instType)
          || !Objects.equals(requestArg.uly, responseArg.uly)
          || !Objects.equals(requestArg.instId, responseArg.instId)) {
        return null;
      }

      reset();
      return switch (response.event) {
        case _subscribe -> SUBSCRIBED;
        case _unsubscribe -> UNSUBSCRIBED;
        default -> throw new IllegalArgumentException(response.event);
      };
    }
  }

  @Override
  protected final void reset() {
    synchronized (pendingRequestHolder) {
      pendingRequestHolder.set(null);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy