private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
    if (logger.isLoggable(Level.FINE)) {
      logger.fine(
          String.format(
              "Channel %s received %s",
              ctx.channel().hashCode(), frame.getClass().getSimpleName()));
    }

    if (frame instanceof CloseWebSocketFrame) {
      handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame);
    } else if (frame instanceof PingWebSocketFrame) {
      ctx.write(new PongWebSocketFrame(frame.isFinalFragment(), frame.rsv(), frame.content()));
    } else if (frame instanceof TextWebSocketFrame) {
      ctx.write(frame);
    } else if (frame instanceof BinaryWebSocketFrame) {
      ctx.write(frame);
    } else if (frame instanceof ContinuationWebSocketFrame) {
      ctx.write(frame);
    } else if (frame instanceof PongWebSocketFrame) {
      frame.release();
      // Ignore
    } else {
      throw new UnsupportedOperationException(
          String.format("%s frame types not supported", frame.getClass().getName()));
    }
  }