001/* 002 * Copyright (C) 2015-2017 Neo Visionaries Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package NeoVisionaries.WebSockets; 017 018 019import java.util.List; 020import java.util.Map; 021 022 023/** 024 * Listener interface to receive WebSocket events. 025 * 026 * <EMBED CLASS='external-html' DATA-FILE-ID=LICENSE><BR /> 027 * 028 * <p> 029 * An implementation of this interface should be added by {@link 030 * WebSocket#addListener(WebSocketListener)} to a {@link WebSocket} 031 * instance before calling {@link WebSocket#connect()}. 032 * </p> 033 * 034 * <p> 035 * {@link WebSocketAdapter} is an empty implementation of this interface. 036 * </p> 037 * 038 * @see WebSocket#addListener(WebSocketListener) 039 * @see WebSocketAdapter 040 */ 041public interface WebSocketListener 042{ 043 /** 044 * Called after the state of the WebSocket changed. 045 * 046 * @param websocket 047 * The WebSocket. 048 * 049 * @param newState 050 * The new state of the WebSocket. 051 * 052 * @throws Exception 053 * An exception thrown by an implementation of this method. 054 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 055 * 056 * @since 1.1 057 */ 058 void onStateChanged(WebSocket websocket, WebSocketState newState) throws Exception; 059 060 061 /** 062 * Called after the opening handshake of the WebSocket connection succeeded. 063 * 064 * @param websocket 065 * The WebSsocket. 066 * 067 * @param headers 068 * HTTP headers received from the server. Keys of the map are 069 * HTTP header names such as {@code "Sec-WebSocket-Accept"}. 070 * Note that the comparator used by the map is {@link 071 * String#CASE_INSENSITIVE_ORDER}. 072 * 073 * @throws Exception 074 * An exception thrown by an implementation of this method. 075 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 076 */ 077 void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception; 078 079 080 /** 081 * Called when {@link WebSocket#connectAsynchronously()} failed. 082 * 083 * <p> 084 * Note that this method is called only when {@code connectAsynchronously()} 085 * was used and the {@link WebSocket#connect() connect()} executed in the 086 * background thread failed. Neither direct synchronous {@code connect()} 087 * nor {@link WebSocket#connect(java.util.concurrent.ExecutorService) 088 * connect(ExecutorService)} will trigger this callback method. 089 * </p> 090 * 091 * @param websocket 092 * The WebSocket. 093 * 094 * @param cause 095 * The exception thrown by {@link WebSocket#connect() connect()} 096 * method. 097 * 098 * @throws Exception 099 * An exception thrown by an implementation of this method. 100 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 101 * 102 * @since 1.8 103 */ 104 void onConnectError(WebSocket websocket, WebSocketException cause) throws Exception; 105 106 107 /** 108 * Called after the WebSocket connection was closed. 109 * 110 * @param websocket 111 * The WebSocket. 112 * 113 * @param serverCloseFrame 114 * The <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1" 115 * >close frame</a> which the server sent to this client. 116 * This may be {@code null}. 117 * 118 * @param clientCloseFrame 119 * The <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1" 120 * >close frame</a> which this client sent to the server. 121 * This may be {@code null}. 122 * 123 * @param closedByServer 124 * {@code true} if the closing handshake was started by the server. 125 * {@code false} if the closing handshake was started by the client. 126 * 127 * @throws Exception 128 * An exception thrown by an implementation of this method. 129 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 130 */ 131 void onDisconnected(WebSocket websocket, 132 WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame, 133 boolean closedByServer) throws Exception; 134 135 136 /** 137 * Called when a frame was received. This method is called before 138 * an <code>on<i>Xxx</i>Frame</code> method is called. 139 * 140 * @param websocket 141 * The WebSocket. 142 * 143 * @param frame 144 * The frame. 145 * 146 * @throws Exception 147 * An exception thrown by an implementation of this method. 148 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 149 */ 150 void onFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 151 152 153 /** 154 * Called when a continuation frame (opcode = 0x0) was received. 155 * 156 * @param websocket 157 * The WebSocket. 158 * 159 * @param frame 160 * The continuation frame. 161 * 162 * @throws Exception 163 * An exception thrown by an implementation of this method. 164 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 165 */ 166 void onContinuationFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 167 168 169 /** 170 * Called when a text frame (opcode = 0x1) was received. 171 * 172 * @param websocket 173 * The WebSocket. 174 * 175 * @param frame 176 * The text frame. 177 * 178 * @throws Exception 179 * An exception thrown by an implementation of this method. 180 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 181 */ 182 void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 183 184 185 /** 186 * Called when a binary frame (opcode = 0x2) was received. 187 * 188 * @param websocket 189 * The WebSocket. 190 * 191 * @param frame 192 * The binary frame. 193 * 194 * @throws Exception 195 * An exception thrown by an implementation of this method. 196 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 197 */ 198 void onBinaryFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 199 200 201 /** 202 * Called when a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1" 203 * >close frame</a> (opcode = 0x8) was received. 204 * 205 * @param websocket 206 * The WebSocket. 207 * 208 * @param frame 209 * The <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>. 210 * 211 * @throws Exception 212 * An exception thrown by an implementation of this method. 213 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 214 */ 215 void onCloseFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 216 217 218 /** 219 * Called when a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2" 220 * >ping frame</a> (opcode = 0x9) was received. 221 * 222 * @param websocket 223 * The WebSocket. 224 * 225 * @param frame 226 * The <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>. 227 * 228 * @throws Exception 229 * An exception thrown by an implementation of this method. 230 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 231 */ 232 void onPingFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 233 234 235 /** 236 * Called when a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3" 237 * >pong frame</a> (opcode = 0xA) was received. 238 * 239 * @param websocket 240 * The WebSocket. 241 * 242 * @param frame 243 * The <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>. 244 * 245 * @throws Exception 246 * An exception thrown by an implementation of this method. 247 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 248 */ 249 void onPongFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 250 251 252 /** 253 * Called when a text message was received. 254 * 255 * <p> 256 * When {@link WebSocket#isDirectTextMessage()} returns {@code true}, 257 * {@link #onTextMessage(WebSocket, byte[])} will be called instead of 258 * this method (since version 2.6). 259 * </p> 260 * 261 * @param websocket 262 * The WebSocket. 263 * 264 * @param text 265 * The text message. 266 * 267 * @throws Exception 268 * An exception thrown by an implementation of this method. 269 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 270 */ 271 void onTextMessage(WebSocket websocket, String text) throws Exception; 272 273 274 /** 275 * Called when a text message was received instead of 276 * {@link #onTextMessage(WebSocket, String)} when {@link WebSocket#isDirectTextMessage()} 277 * returns {@code true}. 278 * 279 * @param websocket 280 * The WebSocket. 281 * 282 * @param data 283 * The UTF-8 byte sequence of the text message. 284 * 285 * @throws Exception 286 * An exception thrown by an implementation of this method. 287 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 288 * 289 * @since 2.6 290 */ 291 void onTextMessage(WebSocket websocket, byte[] data) throws Exception; 292 293 294 /** 295 * Called when a binary message was received. 296 * 297 * @param websocket 298 * The WebSocket. 299 * 300 * @param binary 301 * The binary message. 302 * 303 * @throws Exception 304 * An exception thrown by an implementation of this method. 305 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 306 */ 307 void onBinaryMessage(WebSocket websocket, byte[] binary) throws Exception; 308 309 310 /** 311 * Called before a WebSocket frame is sent. 312 * 313 * @param websocket 314 * The WebSocket. 315 * 316 * @param frame 317 * The WebSocket frame to be sent. 318 * 319 * @throws Exception 320 * An exception thrown by an implementation of this method. 321 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 322 * 323 * @since 1.15 324 */ 325 void onSendingFrame(WebSocket websocket, WebSocketFrame frame) throws Exception; 326 327 328 /** 329 * Called when a WebSocket frame was sent to the server 330 * (but not flushed yet). 331 * 332 * @param websocket 333 * The WebSocket. 334 * 335 * @param frame 336 * The sent frame. 337 * 338 * @throws Exception 339 * An exception thrown by an implementation of this method. 340 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 341 */ 342 void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception; 343 344 345 /** 346 * Called when a WebSocket frame was not sent to the server 347 * because a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1" 348 * >close frame</a> has already been sent. 349 * 350 * <p> 351 * Note that {@code onFrameUnsent} is not called when {@link 352 * #onSendError(WebSocket, WebSocketException, WebSocketFrame) 353 * onSendError} is called. 354 * </p> 355 * 356 * @param websocket 357 * The WebSocket. 358 * 359 * @param frame 360 * The unsent frame. 361 * 362 * @throws Exception 363 * An exception thrown by an implementation of this method. 364 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 365 */ 366 void onFrameUnsent(WebSocket websocket, WebSocketFrame frame) throws Exception; 367 368 369 /** 370 * Called between after a thread is created and before the thread's 371 * {@code start()} method is called. 372 * 373 * @param websocket 374 * The WebSocket. 375 * 376 * @param threadType 377 * The thread type. 378 * 379 * @param thread 380 * The newly created thread instance. 381 * 382 * @throws Exception 383 * An exception thrown by an implementation of this method. 384 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 385 * 386 * @since 2.0 387 */ 388 void onThreadCreated(WebSocket websocket, ThreadType threadType, Thread thread) throws Exception; 389 390 391 /** 392 * Called at the very beginning of the thread's {@code run()} method implementation. 393 * 394 * @param websocket 395 * The WebSocket. 396 * 397 * @param threadType 398 * The thread type. 399 * 400 * @param thread 401 * The thread instance. 402 * 403 * @throws Exception 404 * An exception thrown by an implementation of this method. 405 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 406 * 407 * @since 2.0 408 */ 409 void onThreadStarted(WebSocket websocket, ThreadType threadType, Thread thread) throws Exception; 410 411 412 /** 413 * Called at the very end of the thread's {@code run()} method implementation. 414 * 415 * @param websocket 416 * The WebSocket. 417 * 418 * @param threadType 419 * The thread type. 420 * 421 * @param thread 422 * The thread instance. 423 * 424 * @throws Exception 425 * An exception thrown by an implementation of this method. 426 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 427 * 428 * @since 2.0 429 */ 430 void onThreadStopping(WebSocket websocket, ThreadType threadType, Thread thread) throws Exception; 431 432 433 /** 434 * Call when an error occurred. This method is called before 435 * an <code>on<i>Xxx</i>Error</code> method is called. 436 * 437 * @param websocket 438 * The WebSocket. 439 * 440 * @param cause 441 * An exception that represents the error. 442 * 443 * @throws Exception 444 * An exception thrown by an implementation of this method. 445 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 446 */ 447 void onError(WebSocket websocket, WebSocketException cause) throws Exception; 448 449 450 /** 451 * Called when a WebSocket frame failed to be read from the WebSocket. 452 * 453 * <p> 454 * Some WebSocket server implementations close a WebSocket connection without sending 455 * a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a> to a 456 * client in some cases. Strictly speaking, this behavior is a violation against the 457 * specification (<a href="https://tools.ietf.org/html/rfc6455">RFC 6455</a>). However, 458 * this library has allowed the behavior by default since the version 1.29. Even if 459 * the end of the input stream of a WebSocket connection were reached without a 460 * close frame being received, it would trigger neither {@link #onError(WebSocket, 461 * WebSocketException) onError()} method nor {@link #onFrameError(WebSocket, 462 * WebSocketException, WebSocketFrame) onFrameError()} method. If you want to make 463 * this library report an error in the case, pass {@code false} to {@link 464 * WebSocket#setMissingCloseFrameAllowed(boolean)} method. 465 * </p> 466 * 467 * @param websocket 468 * The WebSocket. 469 * 470 * @param cause 471 * An exception that represents the error. When the error occurred 472 * because of {@link java.io.InterruptedIOException InterruptedIOException}, 473 * {@code exception.getError()} returns {@link WebSocketError#INTERRUPTED_IN_READING}. 474 * For other IO errors, {@code exception.getError()} returns {@link 475 * WebSocketError#IO_ERROR_IN_READING}. Other error codes denote 476 * protocol errors, which imply that some bugs may exist in either 477 * or both of the client-side and the server-side implementations. 478 * 479 * @param frame 480 * The WebSocket frame. If this is not {@code null}, it means that 481 * verification of the frame failed. 482 * 483 * @throws Exception 484 * An exception thrown by an implementation of this method. 485 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 486 */ 487 void onFrameError(WebSocket websocket, WebSocketException cause, WebSocketFrame frame) throws Exception; 488 489 490 /** 491 * Called when it failed to concatenate payloads of multiple frames 492 * to construct a message. The reason of the failure is probably 493 * out-of-memory. 494 * 495 * @param websocket 496 * The WebSocket. 497 * 498 * @param cause 499 * An exception that represents the error. 500 * 501 * @param frames 502 * The list of frames that form a message. The first element 503 * is either a text frame and a binary frame, and the other 504 * frames are continuation frames. 505 * 506 * @throws Exception 507 * An exception thrown by an implementation of this method. 508 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 509 */ 510 void onMessageError(WebSocket websocket, WebSocketException cause, List<WebSocketFrame> frames) throws Exception; 511 512 513 /** 514 * Called when a message failed to be decompressed. 515 * 516 * @param websocket 517 * The WebSocket. 518 * 519 * @param cause 520 * An exception that represents the error. 521 * 522 * @param compressed 523 * The compressed message that failed to be decompressed. 524 * 525 * @throws Exception 526 * An exception thrown by an implementation of this method. 527 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 528 * 529 * @since 1.16 530 */ 531 void onMessageDecompressionError(WebSocket websocket, WebSocketException cause, byte[] compressed) throws Exception; 532 533 534 /** 535 * Called when it failed to convert payload data into a string. 536 * The reason of the failure is probably out-of-memory. 537 * 538 * @param websocket 539 * The WebSocket. 540 * 541 * @param cause 542 * An exception that represents the error. 543 * 544 * @param data 545 * The payload data that failed to be converted to a string. 546 * 547 * @throws Exception 548 * An exception thrown by an implementation of this method. 549 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 550 */ 551 void onTextMessageError(WebSocket websocket, WebSocketException cause, byte[] data) throws Exception; 552 553 554 /** 555 * Called when an error occurred when a frame was tried to be sent 556 * to the server. 557 * 558 * @param websocket 559 * The WebSocket. 560 * 561 * @param cause 562 * An exception that represents the error. 563 * 564 * @param frame 565 * The frame which was tried to be sent. This is {@code null} 566 * when the error code of the exception is {@link 567 * WebSocketError#FLUSH_ERROR FLUSH_ERROR}. 568 * 569 * @throws Exception 570 * An exception thrown by an implementation of this method. 571 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 572 */ 573 void onSendError(WebSocket websocket, WebSocketException cause, WebSocketFrame frame) throws Exception; 574 575 576 /** 577 * Called when an uncaught throwable was detected in either the 578 * reading thread (which reads frames from the server) or the 579 * writing thread (which sends frames to the server). 580 * 581 * @param websocket 582 * The WebSocket. 583 * 584 * @param cause 585 * The cause of the error. 586 * 587 * @throws Exception 588 * An exception thrown by an implementation of this method. 589 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 590 */ 591 void onUnexpectedError(WebSocket websocket, WebSocketException cause) throws Exception; 592 593 594 /** 595 * Called when an <code>on<i>Xxx</i>()</code> method threw a {@code Throwable}. 596 * 597 * @param websocket 598 * The WebSocket. 599 * 600 * @param cause 601 * The {@code Throwable} an <code>on<i>Xxx</i></code> method threw. 602 * 603 * @throws Exception 604 * An exception thrown by an implementation of this method. 605 * The exception is just ignored. 606 * 607 * @since 1.9 608 */ 609 void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception; 610 611 612 /** 613 * Called before an opening handshake is sent to the server. 614 * 615 * @param websocket 616 * The WebSocket. 617 * 618 * @param requestLine 619 * The request line. For example, {@code "GET /chat HTTP/1.1"}. 620 * 621 * @param headers 622 * The HTTP headers. 623 * 624 * @throws Exception 625 * An exception thrown by an implementation of this method. 626 * The exception is passed to {@link #handleCallbackError(WebSocket, Throwable)}. 627 * 628 * @since 1.21 629 */ 630 void onSendingHandshake(WebSocket websocket, String requestLine, List<String[]> headers) throws Exception; 631}