private void sendCloseMessage(CloseReason closeReason) { // 125 is maximum size for the payload of a control message ByteBuffer msg = ByteBuffer.allocate(125); CloseCode closeCode = closeReason.getCloseCode(); // CLOSED_ABNORMALLY should not be put on the wire if (closeCode == CloseCodes.CLOSED_ABNORMALLY) { // PROTOCOL_ERROR is probably better than GOING_AWAY here msg.putShort((short) CloseCodes.PROTOCOL_ERROR.getCode()); } else { msg.putShort((short) closeCode.getCode()); } String reason = closeReason.getReasonPhrase(); if (reason != null && reason.length() > 0) { appendCloseReasonWithTruncation(msg, reason); } msg.flip(); try { wsRemoteEndpoint.startMessageBlock(Constants.OPCODE_CLOSE, msg, true); } catch (IOException ioe) { // Failed to send close message. Close the socket and let the caller // deal with the Exception WebsocketsLogger.ROOT_LOGGER.closeMessageFail(ioe); wsRemoteEndpoint.close(); // Failure to send a close message is not unexpected in the case of // an abnormal closure (usually triggered by a failure to read/write // from/to the client. In this case do not trigger the endpoint's // error handling if (closeCode != CloseCodes.CLOSED_ABNORMALLY) { localEndpoint.onError(this, ioe); } } finally { webSocketContainer.unregisterSession(localEndpoint, this); } }
/** * Called when a close message is received. Should only ever happen once. Also called after a * protocol error when the ProtocolHandler needs to force the closing of the connection. */ public void onClose(CloseReason closeReason) { synchronized (stateLock) { if (state == State.OPEN) { sendCloseMessage(closeReason); fireEndpointOnClose(closeReason); state = State.CLOSED; } // Close the socket wsRemoteEndpoint.close(); } }