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

io.contek.invoker.hbdminverse.api.websocket.common.notification.NotificationWebSocketChannel Maven / Gradle / Ivy

package io.contek.invoker.hbdminverse.api.websocket.common.notification;

import io.contek.invoker.commons.websocket.*;

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

import static io.contek.invoker.commons.websocket.SubscriptionState.*;
import static io.contek.invoker.hbdminverse.api.websocket.user.constants.OpKeys._sub;
import static io.contek.invoker.hbdminverse.api.websocket.user.constants.OpKeys._unsub;

@ThreadSafe
public abstract class NotificationWebSocketChannel<
        Message extends NotificationWebSocketDataMessage, Data>
    extends BaseWebSocketChannel, Message, List> {

  private final NotificationWebSocketRequestIdGenerator requestIdGenerator;

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

  protected NotificationWebSocketChannel(
      NotificationWebSocketChannelId id,
      NotificationWebSocketRequestIdGenerator requestIdGenerator) {
    super(id);
    this.requestIdGenerator = requestIdGenerator;
  }

  @Override
  protected final List getData(Message message) {
    return message.data;
  }

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

      NotificationWebSocketChannelId id = getId();
      NotificationWebSocketSubscriptionRequest request =
          new NotificationWebSocketSubscriptionRequest();
      request.op = _sub;
      request.topic = id.getTopic();
      request.cid = requestIdGenerator.generateNext();
      session.send(request);
      pendingRequestHolder.set(request);
    }

    return SUBSCRIBING;
  }

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

      NotificationWebSocketChannelId id = getId();
      NotificationWebSocketSubscriptionRequest request =
          new NotificationWebSocketSubscriptionRequest();
      request.op = _unsub;
      request.topic = id.getTopic();
      request.cid = requestIdGenerator.generateNext();
      session.send(request);
      pendingRequestHolder.set(request);
    }

    return UNSUBSCRIBING;
  }

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

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

      if (!request.cid.equals(confirmation.cid)) {
        return null;
      }

      if (confirmation.err_code != 0) {
        throw new WebSocketIllegalMessageException(
            confirmation.err_code + ": " + confirmation.err_msg);
      }

      reset();
      return switch (request.op) {
        case _sub -> SUBSCRIBED;
        case _unsub -> UNSUBSCRIBED;
        default -> throw new IllegalStateException();
      };
    }
  }

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy