}
private void sendMessage(int opCode, LoggablePayload loggablePayload, boolean isClosingMessage)
throws IOException {
int length = loggablePayload.getLength();
LoggableOutput output = getSocketWrapper().getLoggableOutput();
byte[] maskBytes = maskStrategy.generate();
synchronized (this) {
if (isOutputClosed()) {
throw new IOException("WebSocket is already closed for output");
}
if (isClosingMessage) {
// Close it before actually sending, because we can fail on it.
setOutputClosed(true);
}
byte firstByte = (byte) (FrameBits.FIN_BIT | OpCode.TEXT);
output.writeByte(firstByte);
int maskFlag = maskBytes == null ? 0 : FrameBits.MASK_BIT;
if (length <= 125) {
output.writeByte((byte) (length | maskFlag));
} else if (length <= FrameBits.MAX_TWO_BYTE_INT) {
output.writeByte((byte) (FrameBits.LENGTH_2_BYTE_CODE | maskFlag));
output.writeByte((byte) ((length >> 8) & 0xFF));
output.writeByte((byte) (length & 0xFF));
} else {
output.writeByte((byte) (FrameBits.LENGTH_8_BYTE_CODE | maskFlag));
output.writeByte((byte) 0);
output.writeByte((byte) 0);
output.writeByte((byte) 0);
output.writeByte((byte) 0);
output.writeByte((byte) (length >>> 24));
output.writeByte((byte) ((length >> 16) & 0xFF));
output.writeByte((byte) ((length >> 8) & 0xFF));
output.writeByte((byte) (length & 0xFF));
}
if (maskBytes != null) {
output.writeBytes(maskBytes);
}
loggablePayload.send(output, maskBytes);
}
output.markSeparatorForLog();
}