stompjs라이브러리를 사용하여 웹 상에서 websocket stomp 전송에 문제가 없었는데 안드로이드에서 websocket 연결 후 stomp CONNECT frame 에 대해 요청한 것으로 보이는 데 서버상에서는 아무런 요청이 오지 않는 문제가 발생했다.
stomp에서 CONNECT 메세지 구조는 아래의 예제와 비슷하다.
COMMAND
header1:value1
header2:value2
...
//빈줄 \n
<optional body>
\0 <-- NULL byte
이 CONNECT 메시지를 서버가 정상적으로 수신하고 인증을 통과하면, 서버는 CONNECTED 프레임을 반환하게 되어 있는데 우선 서버상의 문제가 아닌지 확인이 필요하다.
postman으로 stomp를 진행하려고 하는데 NULL 바이트 전송이 좀 애매해서 대안으로 websocat(CLI도구)를 사용하여 확인했다.
websocat ws://localhost:8082/ws-stomp
CONNECT
accept-version:1.2
heart-beat:10000,10000
^@
CONNECTED version:1.2 heart-beat:0,0 // <-- 응답
참고) Mac에서 NULL 바이트 입력하는 방법
1. Control + V, 그 다음 Control + @ 입력
응답이 정상임을 확인했다.
stompjs를 사용하는 기본 예제는 아래와 같다.
import { Client } from '@stomp/stompjs';
const client = new Client({
brokerURL: 'ws://localhost:8082/ws-stomp',
connectHeaders: {
Authorization: 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json',
},
onConnect: () => {
console.log('✅ STOMP connected');
},
onStompError: frame => {
console.error('❌ STOMP error:', frame);
},
debug: str => {
console.log('STOMP Debug', str); // 디버깅 로그
}
});
client.activate();
debug 에서 CONNECT 로 출력되는 모습에서 빈줄과 NULL바이트가 없어 보였다.
[LOG] STOMP Debug: >>> CONNECT
Authorization:Bearer {JWT 토큰}
Content-Type:application/json
accept-version:1.2,1.1,1.0
heart-beat:10000,10000
// 빈줄이 없음
debug 에서 아래와 같이 수정했을 때
debug: function (str) {
console.log('STOMP Debug', JSON.stringify(str));
}
NULL 바이트가 포함되어 있다면 로그 맨 끝이 이렇게 보여야 한다.
"STOMP Debug >>> CONNECT\naccept-version:1.2\nheart-beat:10000,10000\n...\n\u0000"
\u0000 ← 이게 바로 NULL 바이트
import { Client } from '@stomp/stompjs';
import { Buffer } from 'buffer';
global.Buffer = Buffer; // React Native 환경에서 Buffer 사용을 위해 설정
const client = new Client({
brokerURL: 'ws://yourserver/ws',
connectHeaders: {
Authorization: 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json',
},
debug: (str) => {
console.log('[STOMP DEBUG]', str);
},
webSocketFactory: () => {
const ws = new WebSocket('ws://yourserver/ws');
const originalSend = ws.send;
ws.send = (data) => {
if (typeof data === 'string') {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(data);
originalSend.call(ws, uint8Array);
} else {
originalSend.call(ws, data);
}
};
return ws;
},
});
client.activate();
const client = new Client({
brokerURL: `${env.WS_URL}/ws-stomp`,
appendMissingNULLonIncoming: true,
forceBinaryWSFrames: true,
connectHeaders: {
'Authorization': accessToken,
'Content-Type': 'application/json',
},
위 2개의 옵션을 true로 설정하면 된다. (당연 추천은 2번이다.)
이 설정을 통해 STOMP 메시지가 바이너리 형태로 전송되며, NULL 바이트가 정확하게 포함되어 서버에서 메시지를 올바르게 처리할 수 있게 된다.