DefaultWebSocketFrameEncoder.java
package sprout.server.websocket;
import sprout.beans.annotation.Component;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
public class DefaultWebSocketFrameEncoder implements WebSocketFrameEncoder{
@Override
public byte[] encodeControlFrame(int opcode, byte[] payload) {
if (payload.length > 125) {
throw new IllegalArgumentException("Control frame payload too big (must be <= 125)");
}
byte[] frame = new byte[2 + payload.length];
frame[0] = (byte) (0x80 | opcode); // FIN + opcode
frame[1] = (byte) (payload.length); // No mask, just payload length
System.arraycopy(payload, 0, frame, 2, payload.length);
return frame;
}
@Override
public byte[] encodeBinary(byte[] message) {
int payloadLen = message.length;
ByteArrayOutputStream frameStream = new ByteArrayOutputStream();
// 첫 번째 바이트: FIN + opcode (바이너리 0x2)
frameStream.write(0x82);
// 두 번째 바이트 및 확 길이 필드
if (payloadLen < 126) {
frameStream.write((byte) payloadLen);
} else if (payloadLen <= 65535) {
frameStream.write(126);
frameStream.write((payloadLen >> 8) & 0xFF);
frameStream.write(payloadLen & 0xFF);
} else {
frameStream.write(127);
for (int i = 0; i < 8; i++) {
frameStream.write((byte) ((long)payloadLen >> (8 * (7 - i)) & 0xFF));
}
}
// 페이로드 복사
try {
frameStream.write(message);
} catch (IOException e) {
// ByteArrayOutputStream은 IOException을 던지지 않음
throw new RuntimeException(e);
}
return frameStream.toByteArray();
}
@Override
public byte[] encodeText(String message) {
byte[] payload = message.getBytes(StandardCharsets.UTF_8);
int payloadLen = payload.length;
ByteArrayOutputStream frameStream = new ByteArrayOutputStream();
// 첫 번째 바이트: FIN + opcode (텍스트 = 0x1)
frameStream.write(0x81);
// 두 번째 바이트 및 확장 길이 필드
if (payloadLen < 126) {
frameStream.write((byte) payloadLen);
} else if (payloadLen <= 65535) {
frameStream.write(126);
frameStream.write((payloadLen >> 8) & 0xFF);
frameStream.write(payloadLen & 0xFF);
} else {
frameStream.write(127);
for (int i = 0; i < 8; i++) {
frameStream.write((byte) ((long)payloadLen >> (8 * (7 - i)) & 0xFF));
}
}
// 페이로드 복사
try {
frameStream.write(payload);
} catch (IOException e) {
// ByteArrayOutputStream은 IOException을 던지지 않음
throw new RuntimeException(e);
}
return frameStream.toByteArray();
}
}