Spring Cloud Gateway转发Spring WebSocket

模拟一个广播弹幕的websocket。gateway经过eureka注册中心拉取服务进行转发websocketjavascript

1.搭建 Spring WebSocket

1.1 pom.xml websocket maven依赖

 
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-actuator</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.cloud</groupId>
  11. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-websocket</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-devtools</artifactId>
  20. <optional>true</optional>
  21. </dependency>

1.2 application.yml 配置文件

 
  1. spring:
  2. application:
  3. name: bullet
  4. server:
  5. port: 5678
  6. eureka:
  7. client:
  8. serviceUrl:
  9. defaultZone: http://localhost:1025/eureka/

1.3 BulletApplication websocket启动程序

 
  1. @SpringBootApplication
  2. public class BulletApplication {
  3.  
  4. public static void main(String[] args) {
  5. SpringApplication.run(BulletApplication.class, args);
  6. }
  7. }

1.4 WebSocketAutoConfig websocket配置类

 
  1. @Configuration
  2. @EnableWebSocketMessageBroker
  3. public class WebSocketAutoConfig implements WebSocketMessageBrokerConfigurer {
  4.  
  5. @Override
  6. public void registerStompEndpoints(StompEndpointRegistry registry) {
  7. registry.addEndpoint("/bullet") //开启/bullet端点
  8. .setAllowedOrigins("*") //容许跨域访问
  9. .withSockJS(); //使用sockJS
  10. }
  11.  
  12. @Override
  13. public void configureMessageBroker(MessageBrokerRegistry registry) {
  14. registry.enableSimpleBroker("/toAll"); //订阅Broker名称
  15. }
  16. }

1.5 BulletMessageVO类

使用lombok的@Getter@Setter注解来自动生成get、set方法css

 
  1. @Getter
  2. @Setter
  3. public class BulletMessageVO {
  4. String username;
  5. String message;
  6. }

1.6 BulletController websocket控制器

 
  1. @Controller
  2. public class BulletController {
  3.  
  4. @MessageMapping("/chat")
  5. @SendTo("/toAll/bulletScreen") //SendTo 发送至 Broker 下的指定订阅路径
  6. public String say(BulletMessageVO clientMessage) {
  7. String result=null;
  8. if (clientMessage!=null){
  9. result=clientMessage.getUsername()+":"+clientMessage.getMessage();
  10. }
  11. return result;
  12. }
  13. }

2 搭建 Spring Cloud Gateway

2.1 pom.xml gateway网关maven依赖

 
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-actuator</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-gateway</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.cloud</groupId>
  11. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-devtools</artifactId>
  16. <scope>runtime</scope>
  17. </dependency>

2.2 application.yml gateway网关配置文件

 
  1. spring:
  2. application:
  3. name: gateway
  4. gateway:
  5. routes:
  6. - id: bulletscreen
  7. # 重点!/info必须使用http进行转发,lb表明从注册中心获取服务
  8. uri: lb://bullet
  9. predicates:
  10. # 重点!转发该路径!
  11. - Path=/bullet/info/**
  12. - id: bulletscreen
  13. # 重点!lb:ws://表明从注册中心获取服务,而且转发协议为websocket,这种格式怀疑人生!
  14. uri: lb:ws://bullet
  15. predicates:
  16. # 转发/bullet端点下的全部路径
  17. - Path=/bullet/**
  18. server:
  19. port: 8888
  20. eureka:
  21. client:
  22. serviceUrl:
  23. defaultZone: http://localhost:1025/eureka/

2.3 GatewayApplication gateway启动类

 
  1. @SpringCloudApplication
  2. public class GatewayApplication {
  3.  
  4. public static void main(String[] args) {
  5. SpringApplication.run(GatewayApplication.class, args);
  6. }
  7. }

3 编写html

这个是从网上找来的html代码,能够保存到本地文件,不须要放入服务里面html

 
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>Spring Boot WebSocket+广播式</title>
  6. </head>
  7. <body onload="disconnect()">
  8. <noscript>
  9. <h2 style="color:#ff0000">貌似你的浏览器不支持websocket</h2>
  10. </noscript>
  11. <div>
  12. <div>
  13. <button id="connect" onclick="connect()">链接</button>
  14. <button id="disconnect" onclick="disconnect();">断开链接</button>
  15. </div>
  16. <div id="conversationDiv">
  17. <label>输入你的名字</label> <input type="text" id="name" />
  18. <br>
  19. <label>输入消息</label> <input type="text" id="messgae" />
  20. <button id="send" onclick="send();">发送</button>
  21. <p id="response"></p>
  22. </div>
  23. </div>
  24. <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
  25. <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
  26. <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  27. <script type="text/javascript">
  28. var stompClient = null;
  29. //gateway网关的地址
  30. var host="http://127.0.0.1:8888";
  31. function setConnected(connected) {
  32. document.getElementById('connect').disabled = connected;
  33. document.getElementById('disconnect').disabled = !connected;
  34. document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
  35. $('#response').html();
  36. }
  37.  
  38. function connect() {
  39. //地址+端点路径,构建websocket连接地址
  40. var socket = new SockJS(host+'/bullet');
  41. stompClient = Stomp.over(socket);
  42. stompClient.connect({}, function(frame) {
  43. setConnected(true);
  44. console.log('Connected:' + frame);
  45. //监听的路径以及回调
  46. stompClient.subscribe('/toAll/bulletScreen', function(response) {
  47. showResponse(response.body);
  48. });
  49.  
  50. });
  51. }
  52.  
  53.  
  54. function disconnect() {
  55. if (stompClient != null) {
  56. stompClient.disconnect();
  57. }
  58. setConnected(false);
  59. console.log("Disconnected");
  60. }
  61.  
  62. function send() {
  63. var name = $('#name').val();
  64. var message = $('#messgae').val();
  65. //发送消息的路径
  66. stompClient.send("/chat", {}, JSON.stringify({username:name,message:message}));
  67. }
  68.  
  69. function showResponse(message) {
  70. var response = $('#response');
  71. response.html(message);
  72. }
  73. </script>
  74. </body>
  75. </html>

4 启动程序

  1. 启动Eureka 服务端,开启注册中心
  2. 启动Bullet WebSocket程序
  3. 启动GateWay网关

5 测试程序

  1. 开启多个html页面,并打开控制台
    java

  2. 在多个页面中点击链接按钮,观察控制台是否链接成功
    jquery

  1. 输入名字和消息,观察是否成功进行广播

6 源码

https://github.com/naah69/SpringCloud-Gateway-WebSocket-Demogit