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

io.cettia.asity.websocket.AbstractServerWebSocket Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/*
 * Copyright 2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.cettia.asity.websocket;

import io.cettia.asity.action.Action;
import io.cettia.asity.action.Actions;
import io.cettia.asity.action.SimpleActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.util.List;

/**
 * Abstract base class for {@link ServerWebSocket}.
 *
 * @author Donghwan Kim
 */
public abstract class AbstractServerWebSocket implements ServerWebSocket {

  protected final Actions textActions = new SimpleActions<>();
  protected final Actions binaryActions = new SimpleActions<>();
  protected final Actions errorActions = new SimpleActions<>();
  protected final Actions closeActions = new SimpleActions<>(new Actions.Options().once
    (true).memory(true));

  private final Logger logger = LoggerFactory.getLogger(AbstractServerWebSocket.class);
  private State state = State.OPEN;

  public AbstractServerWebSocket() {
    errorActions.add(throwable -> logger.trace("{} has received a throwable {}", AbstractServerWebSocket.this, throwable));
    closeActions.add($ -> {
      state = State.CLOSED;
      logger.trace("{} has been closed", AbstractServerWebSocket.this);
    });
  }

  @Override
  public String header(String name) {
    List headers = headers(name);
    return headers != null && headers.size() > 0 ? headers.get(0) : null;
  }

  @Override
  public void close() {
    logger.trace("{} has started to close the connection", this);
    if (state != State.CLOSING && state != State.CLOSED) {
      state = State.CLOSING;
      doClose();
    }
  }

  protected abstract void doClose();

  @Override
  public ServerWebSocket send(String data) {
    logger.trace("{} sends a text message {}", this, data);
    doSend(data);
    return this;
  }

  @Override
  public ServerWebSocket send(ByteBuffer byteBuffer) {
    if (logger.isTraceEnabled() && byteBuffer.hasArray()) {
      logger.trace("{} sends a text message {}", this, new String(byteBuffer.array()));
    }
    doSend(byteBuffer);
    return this;
  }

  protected abstract void doSend(ByteBuffer byteBuffer);

  protected abstract void doSend(String data);

  @Override
  public ServerWebSocket ontext(Action action) {
    textActions.add(action);
    return this;
  }

  @Override
  public ServerWebSocket onbinary(Action action) {
    binaryActions.add(action);
    return this;
  }

  @Override
  public ServerWebSocket onclose(Action action) {
    closeActions.add(action);
    return this;
  }

  @Override
  public ServerWebSocket onerror(Action action) {
    errorActions.add(action);
    return this;
  }

  /**
   * Represents the state of the connection.
   *
   * @author Donghwan Kim
   * @see The
   * WebSocket API by W3C - The readyState attribute
   */
  private static enum State {

    /**
     * The connection has not yet been established.
     */
    CONNECTING,

    /**
     * The WebSocket connection is established and communication is possible.
     */
    OPEN,

    /**
     * The close() method has been invoked.
     */
    CLOSING,

    /**
     * The connection has been closed or could not be opened.
     */
    CLOSED

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy