diff --git a/springboot-webflux-8-websocket/pom.xml b/springboot-webflux-8-websocket/pom.xml
new file mode 100755
index 0000000..c141f78
--- /dev/null
+++ b/springboot-webflux-8-websocket/pom.xml
@@ -0,0 +1,45 @@
+
+
+ 4.0.0
+
+ springboot
+ springboot-webflux-8-websocket
+ 0.0.1-SNAPSHOT
+ springboot-webflux-8-websocket :: Spring Boot WebFlux 中 WebSocket 实现通信
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.1.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/Application.java b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/Application.java
new file mode 100644
index 0000000..a472cd5
--- /dev/null
+++ b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/Application.java
@@ -0,0 +1,21 @@
+package org.spring.springboot;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Spring Boot 应用启动类
+ *
+ * Created by bysocket on 09/29/2017.
+ */
+// Spring Boot 应用的标识
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ // 程序启动入口
+ // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
+ SpringApplication.run(Application.class,args);
+
+ }
+}
diff --git a/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/config/WebSocketConfiguration.java b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/config/WebSocketConfiguration.java
new file mode 100644
index 0000000..5c891c1
--- /dev/null
+++ b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/config/WebSocketConfiguration.java
@@ -0,0 +1,35 @@
+package org.spring.springboot.config;
+
+import org.spring.springboot.handler.EchoHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.web.reactive.HandlerMapping;
+import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
+import org.springframework.web.reactive.socket.WebSocketHandler;
+import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class WebSocketConfiguration {
+
+ @Autowired
+ @Bean
+ public HandlerMapping webSocketMapping(final EchoHandler echoHandler) {
+ final Map map = new HashMap<>();
+ map.put("/echo", echoHandler);
+
+ final SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
+ mapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
+ mapping.setUrlMap(map);
+ return mapping;
+ }
+
+ @Bean
+ public WebSocketHandlerAdapter handlerAdapter() {
+ return new WebSocketHandlerAdapter();
+ }
+}
diff --git a/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/handler/EchoHandler.java b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/handler/EchoHandler.java
new file mode 100644
index 0000000..8e36e59
--- /dev/null
+++ b/springboot-webflux-8-websocket/src/main/java/org/spring/springboot/handler/EchoHandler.java
@@ -0,0 +1,17 @@
+
+package org.spring.springboot.handler;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.socket.WebSocketHandler;
+import org.springframework.web.reactive.socket.WebSocketSession;
+import reactor.core.publisher.Mono;
+
+@Component
+public class EchoHandler implements WebSocketHandler {
+ @Override
+ public Mono handle(final WebSocketSession session) {
+ return session.send(
+ session.receive()
+ .map(msg -> session.textMessage("服务端返回:小明, -> " + msg.getPayloadAsText())));
+ }
+}
diff --git a/springboot-webflux-8-websocket/src/main/resources/application.properties b/springboot-webflux-8-websocket/src/main/resources/application.properties
new file mode 100644
index 0000000..e69de29
diff --git a/springboot-webflux-8-websocket/src/main/resources/websocket-client.html b/springboot-webflux-8-websocket/src/main/resources/websocket-client.html
new file mode 100644
index 0000000..2f26cc2
--- /dev/null
+++ b/springboot-webflux-8-websocket/src/main/resources/websocket-client.html
@@ -0,0 +1,28 @@
+
+
+
+
+ Client WebSocket
+
+
+
+
+
+
+
diff --git a/springboot-webflux-8-websocket/src/test/java/WSClient.java b/springboot-webflux-8-websocket/src/test/java/WSClient.java
new file mode 100644
index 0000000..0180132
--- /dev/null
+++ b/springboot-webflux-8-websocket/src/test/java/WSClient.java
@@ -0,0 +1,19 @@
+import org.springframework.web.reactive.socket.WebSocketMessage;
+import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
+import org.springframework.web.reactive.socket.client.WebSocketClient;
+import reactor.core.publisher.Flux;
+
+import java.net.URI;
+import java.time.Duration;
+
+public class WSClient {
+ public static void main(final String[] args) {
+ final WebSocketClient client = new ReactorNettyWebSocketClient();
+ client.execute(URI.create("ws://localhost:8080/echo"), session ->
+ session.send(Flux.just(session.textMessage("你好")))
+ .thenMany(session.receive().take(1).map(WebSocketMessage::getPayloadAsText))
+ .doOnNext(System.out::println)
+ .then())
+ .block(Duration.ofMillis(5000));
+ }
+}