Interface WebSocket
Interface WebSocket
public interface WebSocket
WebSocket 클라이언트예요. WebSocket 인스턴스는 WebSocket.Builder를 통해 만들어져요. WebSocket은 입력(input)과 출력(output) 양쪽을 가져요. 이 양쪽은 서로 독립적이에요. 한 쪽은 열려 있거나(open) 닫혀 있을(closed) 수 있어요. 한 번 닫히면 그 쪽은 닫힌 채로 유지돼요. WebSocket 메시지는 WebSocket을 통해 보내지고 그와 연관된 WebSocket.Listener를 통해 받아져요. 메시지는 WebSocket의 출력이 닫힐 때까지 보낼 수 있고, WebSocket의 입력이 닫힐 때까지 받을 수 있어요. 보내기(send) 메서드는 WebSocket의 sendText, sendBinary, sendPing, sendPong, sendClose 메서드 중 하나예요. 보내기 메서드는 보내기 연산을 시작하고, 연산이 완료되면 완료되는 CompletableFuture를 반환해요. CompletableFuture가 정상적으로 완료되면 연산이 성공한 것으로 간주돼요. CompletableFuture가 예외적으로 완료되면 연산이 실패한 것으로 간주돼요. 시작되었지만 아직 완료되지 않은 연산은 보류 중(pending)으로 간주돼요. 받기(receive) 메서드는 Listener의 onText, onBinary, onPing, onPong, onClose 메서드 중 하나예요. WebSocket은 리스너에서 받기 메서드를 호출함으로써 받기 연산을 시작해요. 리스너는 연산이 완료되면 완료되는 CompletionStage를 반환해야 해요. 메시지 수신을 제어하기 위해 WebSocket은 내부 카운터를 유지해요. 이 카운터의 값은 WebSocket이 받기 메서드를 아직 호출해야 하는 횟수예요. 이 카운터가 0인 동안 WebSocket은 받기 메서드를 호출하지 않아요. request(n)이 호출되면 카운터는 n만큼 증가해요. WebSocket이 받기 메서드를 호출하면 카운터는 1만큼 감소해요. onOpen과 onError는 받기 메서드가 아니에요. WebSocket은 리스너의 다른 어떤 메서드보다 먼저 onOpen을 호출해요. WebSocket은 onOpen을 최대 한 번 호출해요. WebSocket은 언제든지 onError를 호출할 수 있어요. WebSocket이 onError나 onClose를 호출하면 카운터 값과 무관하게 더 이상 리스너의 메서드가 호출되지 않아요. 새로 만들어진 WebSocket의 카운터는 0이에요. 달리 명시되지 않는 한, null 인자는 WebSocket의 메서드가 NullPointerException을 던지게 하며, 마찬가지로 WebSocket은 Listener의 메서드에 null 인자를 전달하지 않아요. NullPointerException, IllegalArgumentException, IllegalStateException 예외 중 하나로 던지거나 완료되는 CompletableFuture를 반환하는 호출에 의해 WebSocket의 상태는 변경되지 않아요. WebSocket은 받은 Ping·Close 메시지를 (WebSocket 프로토콜에 따라) Pong·Close 메시지로 응답해 자동으로 처리해요. 리스너가 Ping이나 Close 메시지를 받으면 리스너로부터 요구되는 필수 동작은 없어요.
NORMAL_CLOSURE
static final int NORMAL_CLOSURE
정상 종료(normal closure)를 나타내는 WebSocket Close 메시지 상태 코드(1000)로, 연결이 수립된 목적이 충족되었음을 의미해요.
- See Also: sendClose(int, String), WebSocket.Listener.onClose(WebSocket, int, String), 상수 필드 값(Constant Field Values)
sendText
CompletableFuture<WebSocket> sendText(CharSequence data,
boolean last)
주어진 문자 시퀀스의 문자들로 텍스트 데이터를 보내요. 이 메서드가 반환한 CompletableFuture가 완료될 때까지 문자 시퀀스를 수정해서는 안 돼요. 이 메서드가 반환한 CompletableFuture는 다음으로 예외적으로 완료될 수 있어요:
-
IllegalStateException- 보류 중인 텍스트/바이너리 보내기 연산이 있거나, 이전 바이너리 데이터가 메시지를 완성하지 못할 때 -
IOException- I/O 오류가 발생하거나 출력이 닫혔을 때 -
Implementation Note: data가 잘못된(malformed) UTF-16 시퀀스이면 연산이
IOException으로 실패할 거예요 -
Parameters: data - 데이터
-
Returns: 데이터가 보내졌을 때 이 WebSocket과 함께 완료되는
CompletableFuture
sendBinary
CompletableFuture<WebSocket> sendBinary(ByteBuffer data,
boolean last)
주어진 버퍼의 바이트들로 바이너리 데이터를 보내요. 데이터는 버퍼의 position에서 limit까지의 바이트에 있어요. 이 메서드가 반환한 CompletableFuture의 정상 완료 시 버퍼에는 남은 바이트가 없을 거예요. 그 후까지 버퍼에 접근해서는 안 돼요. 이 메서드가 반환한 CompletableFuture는 다음으로 예외적으로 완료될 수 있어요:
-
IllegalStateException- 보류 중인 텍스트/바이너리 보내기 연산이 있거나, 이전 텍스트 데이터가 메시지를 완성하지 못할 때 -
IOException- I/O 오류가 발생하거나 출력이 닫혔을 때 -
Parameters: data - 데이터
-
Returns: 데이터가 보내졌을 때 이 WebSocket과 함께 완료되는
CompletableFuture
sendPing
CompletableFuture<WebSocket> sendPing(ByteBuffer message)
주어진 버퍼의 바이트들로 Ping 메시지를 보내요. 메시지는 버퍼의 position에서 limit까지의 125바이트를 넘지 않는 것으로 구성돼요. 이 메서드가 반환한 CompletableFuture의 정상 완료 시 버퍼에는 남은 바이트가 없을 거예요. 그 후까지 버퍼에 접근해서는 안 돼요. 이 메서드가 반환한 CompletableFuture는 다음으로 예외적으로 완료될 수 있어요:
-
IllegalStateException- 보류 중인 ping/pong 보내기 연산이 있을 때 -
IllegalArgumentException- 메시지가 너무 길 때 -
IOException- I/O 오류가 발생하거나 출력이 닫혔을 때 -
Parameters: message - 메시지
-
Returns: Ping 메시지가 보내졌을 때 이 WebSocket과 함께 완료되는
CompletableFuture
sendPong
CompletableFuture<WebSocket> sendPong(ByteBuffer message)
주어진 버퍼의 바이트들로 Pong 메시지를 보내요. 메시지는 버퍼의 position에서 limit까지의 125바이트를 넘지 않는 것으로 구성돼요. 이 메서드가 반환한 CompletableFuture의 정상 완료 시 버퍼에는 남은 바이트가 없을 거예요. 그 후까지 버퍼에 접근해서는 안 돼요. WebSocket 구현이 ping을 받으면 자동으로 상호적인 pong을 보낼 것이므로, pong 메시지를 명시적으로 보내는 것은 거의 필요하지 않아요. 이 메서드가 반환한 CompletableFuture는 다음으로 예외적으로 완료될 수 있어요:
-
IllegalStateException- 보류 중인 ping/pong 보내기 연산이 있을 때 -
IllegalArgumentException- 메시지가 너무 길 때 -
IOException- I/O 오류가 발생하거나 출력이 닫혔을 때 -
Parameters: message - 메시지
-
Returns: Pong 메시지가 보내졌을 때 이 WebSocket과 함께 완료되는
CompletableFuture
sendClose
CompletableFuture<WebSocket> sendClose(int statusCode,
String reason)
주어진 상태 코드와 reason으로 Close 메시지를 보내 이 WebSocket 출력의 정돈된 종료를 시작해요. statusCode는 범위 1000 <= code <= 4999의 정수예요. 상태 코드 1002, 1003, 1006, 1007, 1009, 1010, 1012, 1013, 1015는 불법이에요. 다른 상태 코드에 대한 동작은 구현별이에요. 합법적인 reason은 UTF-8 표현이 123바이트보다 길지 않은 문자열이에요. 이 메서드가 반환한 CompletableFuture는 다음으로 예외적으로 완료될 수 있어요:
IllegalArgumentException- statusCode가 불법이거나 reason이 불법일 때IOException- I/O 오류가 발생하거나 출력이 닫혔을 때
이 메서드가 반환한 CompletableFuture가 IllegalArgumentException으로 완료되거나 메서드가 NullPointerException을 던지지 않는 한 출력이 닫힐 거예요. 아직 닫히지 않았다면, Close 메시지를 받거나 abort가 호출되거나 오류가 발생할 때까지 입력은 열려 있게 돼요.
- API Note: 전형적인 경우 상태 코드로 제공된 정수 상수
NORMAL_CLOSURE를, reason으로 빈 문자열을 사용하세요:CompletableFuture<WebSocket> webSocket = ... webSocket.thenCompose(ws -> ws.sendText("Hello, ", false)) .thenCompose(ws -> ws.sendText("world!", true)) .thenCompose(ws -> ws.sendClose(WebSocket.NORMAL_CLOSURE, "")) .join();sendClose메서드는 이 WebSocket의 입력을 닫지 않아요. Close 메시지를 보내 이 WebSocket의 출력만 닫을 뿐이에요. 입력 닫기를 강제하려면abort메서드를 호출하세요. 다음은 Close 메시지를 보낸 다음 타이머를 시작하는 애플리케이션의 예시예요. 지정된 타임아웃 안에 데이터가 수신되지 않으면 타이머가 울리고 알람이 WebSocket을 중단해요:MyAlarm alarm = new MyAlarm(webSocket::abort); WebSocket.Listener listener = new WebSocket.Listener() { public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) { alarm.snooze(); ... } ... }; ... Runnable startTimer = () -> { MyTimer idleTimer = new MyTimer(); idleTimer.add(alarm, 30, TimeUnit.SECONDS); }; webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").thenRun(startTimer); - Parameters: statusCode - 상태 코드
- Returns: Close 메시지가 보내졌을 때 이 WebSocket과 함께 완료되는
CompletableFuture
request
void request(long n)
받기 메서드 호출의 카운터를 증가시켜요. 이 WebSocket은 연관된 리스너에서 onText, onBinary, onPing, onPong, onClose 메서드(즉 받기 메서드)를 최대 n회 더 호출할 거예요.
- API Note: 이 메서드의 매개변수는 이 WebSocket이 연관된 리스너에게 요청하는 호출 수이지 메시지 수가 아니에요. 때로는 메시지가 단일 호출로 리스너에게 전달될 수 있지만 항상 그런 것은 아니에요. 예를 들어 Ping, Pong, Close 메시지는 각각
onPing,onPong,onClose메서드의 단일 호출로 전달돼요. 그러나 Text·Binary 메시지가onText·onBinary메서드의 단일 호출로 전달되는지 여부는 이 메서드들의 boolean 인자(last)에 따라 달라져요. last가 false이면 호출에 전달된 것보다 메시지에 더 많은 것이 있다는 뜻이에요. 다음은 완전한 메시지가 축적될 때까지 호출을 한 번에 하나씩 요청한 다음 결과를 처리하는 리스너의 예시예요:WebSocket.Listener listener = new WebSocket.Listener() { StringBuilder text = new StringBuilder(); public CompletionStage<?> onText(WebSocket webSocket, CharSequence message, boolean last) { text.append(message); if (last) { processCompleteTextMessage(text); text = new StringBuilder(); } webSocket.request(1); return null; } }; - Parameters: n - 호출 수
- Throws: IllegalArgumentException - n <= 0일 때
getSubprotocol
String getSubprotocol()
이 WebSocket이 사용하는 하위 프로토콜(subprotocol)을 반환해요.
- Returns: 하위 프로토콜, 또는 하위 프로토콜이 없으면 빈 문자열
isOutputClosed
boolean isOutputClosed()
이 WebSocket의 출력이 닫혔는지 알려줘요. 이 메서드가 true를 반환하면 이후의 호출도 true를 반환할 거예요.
- Returns: 닫혔으면 true, 그렇지 않으면 false
isInputClosed
boolean isInputClosed()
이 WebSocket의 입력이 닫혔는지 알려줘요. 이 메서드가 true를 반환하면 이후의 호출도 true를 반환할 거예요.
- Returns: 닫혔으면 true, 그렇지 않으면 false
abort
void abort()
이 WebSocket의 입력과 출력을 갑자기 닫아요. 이 메서드가 반환할 때 입력과 출력 모두 닫혔을 거예요. 보류 중인 어떤 보내기 연산도 IOException으로 실패할 거예요. 이후의 abort 호출은 효과가 없어요.