001/* 002 * Copyright 2002-2018 the original author or authors. 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 * https://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 */ 016 017package org.springframework.web.reactive.socket; 018 019import java.util.Collections; 020import java.util.List; 021 022import org.reactivestreams.Publisher; 023import reactor.core.publisher.Mono; 024 025/** 026 * Handler for a WebSocket session. 027 * 028 * <p>A server {@code WebSocketHandler} is mapped to requests with 029 * {@link org.springframework.web.reactive.handler.SimpleUrlHandlerMapping 030 * SimpleUrlHandlerMapping} and 031 * {@link org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter 032 * WebSocketHandlerAdapter}. A client {@code WebSocketHandler} is passed to the 033 * {@link org.springframework.web.reactive.socket.client.WebSocketClient 034 * WebSocketClient} execute method. 035 * 036 * <p>Use {@link WebSocketSession#receive() session.receive()} to compose on 037 * the inbound message stream, and {@link WebSocketSession#send(Publisher) 038 * session.send(publisher)} for the outbound message stream. Below is an 039 * example, combined flow to process inbound and to send outbound messages: 040 * 041 * <pre class="code"> 042 * class ExampleHandler implements WebSocketHandler { 043 044 * @Override 045 * public Mono<Void> handle(WebSocketSession session) { 046 * 047 * Flux<WebSocketMessage> output = session.receive() 048 * .doOnNext(message -> { 049 * // ... 050 * }) 051 * .concatMap(message -> { 052 * // ... 053 * }) 054 * .map(value -> session.textMessage("Echo " + value)); 055 * 056 * return session.send(output); 057 * } 058 * } 059 * </pre> 060 * 061 * <p>If processing inbound and sending outbound messages are independent 062 * streams, they can be joined together with the "zip" operator: 063 * 064 * <pre class="code"> 065 * class ExampleHandler implements WebSocketHandler { 066 067 * @Override 068 * public Mono<Void> handle(WebSocketSession session) { 069 * 070 * Mono<Void> input = session.receive() 071 * .doOnNext(message -> { 072 * // ... 073 * }) 074 * .concatMap(message -> { 075 * // ... 076 * }) 077 * .then(); 078 * 079 * Flux<String> source = ... ; 080 * Mono<Void> output = session.send(source.map(session::textMessage)); 081 * 082 * return Mono.zip(input, output).then(); 083 * } 084 * } 085 * </pre> 086 * 087 * <p>A {@code WebSocketHandler} must compose the inbound and outbound streams 088 * into a unified flow and return a {@code Mono<Void>} that reflects the 089 * completion of that flow. That means there is no need to check if the 090 * connection is open, since Reactive Streams signals will terminate activity. 091 * The inbound stream receives a completion/error signal, and the outbound 092 * stream receives a cancellation signal. 093 * 094 * @author Rossen Stoyanchev 095 * @since 5.0 096 */ 097public interface WebSocketHandler { 098 099 /** 100 * Return the list of sub-protocols supported by this handler. 101 * <p>By default an empty list is returned. 102 */ 103 default List<String> getSubProtocols() { 104 return Collections.emptyList(); 105 } 106 107 /** 108 * Invoked when a new WebSocket connection is established, and allows 109 * handling of the session. 110 * 111 * <p>See the class-level doc and the reference for more details and 112 * examples of how to handle the session. 113 * 114 * @param session the session to handle 115 * @return indicates when appilcation handling of the session is complete, 116 * which should reflect the completion of the inbound message stream 117 * (i.e. connection closing) and possibly the completion of the outbound 118 * message stream and the writing of messages. 119 */ 120 Mono<Void> handle(WebSocketSession session); 121 122}