public void eot() {
   if (getReadyState() == READYSTATE.NOT_YET_CONNECTED) {
     closeConnection(CloseFrame.NEVER_CONNECTED, true);
   } else if (flushandclosestate) {
     closeConnection(closecode, closemessage, closedremotely);
   } else if (draft.getCloseHandshakeType() == CloseHandshakeType.NONE) {
     closeConnection(CloseFrame.NORMAL, true);
   } else if (draft.getCloseHandshakeType() == CloseHandshakeType.ONEWAY) {
     if (role == Role.SERVER) closeConnection(CloseFrame.ABNORMAL_CLOSE, true);
     else closeConnection(CloseFrame.NORMAL, true);
   } else {
     closeConnection(CloseFrame.ABNORMAL_CLOSE, true);
   }
 }
 private void close(int code, String message, boolean remote) {
   if (readystate != READYSTATE.CLOSING && readystate != READYSTATE.CLOSED) {
     if (readystate == READYSTATE.OPEN) {
       if (code == CloseFrame.ABNORMAL_CLOSE) {
         assert (remote == false);
         readystate = READYSTATE.CLOSING;
         flushAndClose(code, message, false);
         return;
       }
       if (draft.getCloseHandshakeType() != CloseHandshakeType.NONE) {
         try {
           if (!remote) {
             try {
               wsl.onWebsocketCloseInitiated(this, code, message);
             } catch (RuntimeException e) {
               wsl.onWebsocketError(this, e);
             }
           }
           sendFrame(new CloseFrameBuilder(code, message));
         } catch (InvalidDataException e) {
           wsl.onWebsocketError(this, e);
           flushAndClose(CloseFrame.ABNORMAL_CLOSE, "generated frame is invalid", false);
         }
       }
       flushAndClose(code, message, remote);
     } else if (code == CloseFrame.FLASHPOLICY) {
       assert (remote);
       flushAndClose(CloseFrame.FLASHPOLICY, message, true);
     } else {
       flushAndClose(CloseFrame.NEVER_CONNECTED, message, false);
     }
     if (code == CloseFrame.PROTOCOL_ERROR) // this endpoint found a PROTOCOL_ERROR
     flushAndClose(code, message, remote);
     readystate = READYSTATE.CLOSING;
     tmpHandshakeBytes = null;
     return;
   }
 }
  private void decodeFrames(ByteBuffer socketBuffer) {

    List<Framedata> frames;
    try {
      frames = draft.translateFrame(socketBuffer);
      for (Framedata f : frames) {
        if (DEBUG) System.out.println("matched frame: " + f);
        Opcode curop = f.getOpcode();
        boolean fin = f.isFin();

        if (curop == Opcode.CLOSING) {
          int code = CloseFrame.NOCODE;
          String reason = "";
          if (f instanceof CloseFrame) {
            CloseFrame cf = (CloseFrame) f;
            code = cf.getCloseCode();
            reason = cf.getMessage();
          }
          if (readystate == READYSTATE.CLOSING) {
            // complete the close handshake by disconnecting
            closeConnection(code, reason, true);
          } else {
            // echo close handshake
            if (draft.getCloseHandshakeType() == CloseHandshakeType.TWOWAY)
              close(code, reason, true);
            else flushAndClose(code, reason, false);
          }
          continue;
        } else if (curop == Opcode.PING) {
          wsl.onWebsocketPing(this, f);
          continue;
        } else if (curop == Opcode.PONG) {
          wsl.onWebsocketPong(this, f);
          continue;
        } else if (!fin || curop == Opcode.CONTINUOUS) {
          if (curop != Opcode.CONTINUOUS) {
            if (current_continuous_frame_opcode != null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed.");
            current_continuous_frame_opcode = curop;
          } else if (fin) {
            if (current_continuous_frame_opcode == null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
            current_continuous_frame_opcode = null;
          } else if (current_continuous_frame_opcode == null) {
            throw new InvalidDataException(
                CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
          }
          try {
            wsl.onWebsocketMessageFragment(this, f);
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }

        } else if (current_continuous_frame_opcode != null) {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed.");
        } else if (curop == Opcode.TEXT) {
          try {
            wsl.onWebsocketMessage(this, Charsetfunctions.stringUtf8(f.getPayloadData()));
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else if (curop == Opcode.BINARY) {
          try {
            wsl.onWebsocketMessage(this, f.getPayloadData());
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected");
        }
      }
    } catch (InvalidDataException e1) {
      wsl.onWebsocketError(this, e1);
      close(e1);
      return;
    }
  }