TCP 또는 WebSocket같은 양방향 프로토콜을 기반으로 동작한다.
Message Broker를 이용해서 Publish-Subscribe 메커니즘을 제공한다.
STOMP를 사용하게 되면 단순한 bianry, text가 아닌 규격을 갖춘 message를 보낼 수 있게된다.
그리고 SEND, SUBSCRIBE 커맨드를 통해 subscribe, publish메커니즘을 사용할 수 있게 된다.
COMMOND
header1:value1
header2:value2
BODY^@
// var socket = new WebSocket(url)
var socket = new SockJS(url)
// reconnection을 위해 함수타입으로 감싸준다.
var stompClient = stomp.over(() => socket)
// STOMP 다음 버전에서 바뀔 예정
// var stompClient = stomp.webSocketFactory = () => socket
stompClient.connect(header, connectCallback, errorCallback, closeEventCallback)
기본 WebSocket 인터페이스를 사용해도 되지만 emulation을 위해 Sock.js와 함께 쓴다.
connect 메서드를 통해 연결하는데, parameter에 2개 이상의 값이 들어간다.
header
: 통신에 필요한 헤더 (토큰 등)connectCallback
: 연결이 성사되었을 때 호출할 함수errorCallback
: 에러가 났을 때 호출할 함수closeEventCallback
: 연결이 종료되었을 때 호출할 함수parameter에는 5개 이상의 값도 들어갈 수 있는데, 그 목록은 다음 코드에서 확인할 수 있다.
private _parseConnect(...args: any[]): any {
let closeEventCallback;
let connectCallback;
let errorCallback;
let headers: StompHeaders = {};
if (args.length < 2) {
throw new Error('Connect requires at least 2 arguments');
}
if (typeof args[1] === 'function') {
[headers, connectCallback, errorCallback, closeEventCallback] = args;
} else {
switch (args.length) {
case 6:
[
headers.login,
headers.passcode,
connectCallback,
errorCallback,
closeEventCallback,
headers.host,
] = args;
break;
default:
[
headers.login,
headers.passcode,
connectCallback,
errorCallback,
closeEventCallback,
] = args;
}
}
return [headers, connectCallback, errorCallback, closeEventCallback];
}
위 4개에선 볼 수 없었던 headers.login, headers.passcode, headers.host의 값이 있고, 결국엔 headers로 합쳐져서 리턴되는 형태이다.
이렇게 연결이 설정되면 데이터를 주고받을 수 있다.
stompClient.subscribe(url, stompFrameHandler)
초기화를 통해 생성한 client의 subscribe 메서드로 엔드포인트에 핸들러를 부착하여 받은 데이터를 처리한다.
Spring에서 STOMP를 썼을 때, Spring 애플리케이션은 클라이언트를 위한 STOMP브로커가 된다.
메시지의 목적지에 따라 먼저 컨트롤러를 거칠지, 바로 브로커를 통해 메시지르 전달할지 조정할 수 있다.
위 그림에서
/app
이라는 prefix를 통해 메시지를 전달했을 때/topic
이라는 prefix를 통해 메시지를 전달했을 때