zoukankan      html  css  js  c++  java
  • 微服务学习----Spring Cloud 使用 webSocket

    Spring Cloud 使用 webSocket

    网关配置

    spring cloud 的网关组件有zuul和getway

    getway

    base:
      config:
        nacos:
          nacoshost: localhost
          port: 8848
    
    spring:
      application:
        name: gateway
      main:
        allow-bean-definition-overriding: true
      cloud:
        nacos:
          discovery:
            server-addr: ${base.config.nacos.nacoshost}:${base.config.nacos.port}
        gateway:
          discovery:
            locator:
              enabled: true
          routes:
            #  websocket
            - id: CLOUD-WEBSOCKET
              uri: lb:ws://cloud-websocket
              predicates:
                - Path=/cloud-websocket/**
    server:
      port: 8888
    

    配置网关的时候注意添加ws协议。

    zuul

    zuul只能管理http请求,不推荐使用zuul管理websocket连接,推荐直连。

    服务端

    • 添加maven依赖

      • <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-websocket</artifactId>
                </dependency>
        
    • 添加webSocket 配置

      • @Configuration
        @EnableWebSocket
        public class WebsocketConfiguration implements WebSocketConfigurer {
            @Override
            public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
                // webSocket通道
                // 指定处理器和路径
                registry.addHandler(new WebSocketHandler(), "/websocket")
                        // 指定自定义拦截器
                        .addInterceptors(new WebSocketInterceptor())
                        // 允许跨域
                        .setAllowedOrigins("*");
                // sockJs通道
                registry.addHandler(new WebSocketHandler(), "/sock-js")
                        .addInterceptors(new WebSocketInterceptor())
                        .setAllowedOrigins("*")
                        // 开启sockJs支持
                        .withSockJS();
            }
        }
        
    • 添加处理器

      • package com.auexpress.cloud.handler;
        
        import com.alibaba.fastjson.JSONObject;
        import org.apache.commons.lang3.StringUtils;
        import org.springframework.web.socket.*;
        import org.springframework.web.socket.handler.AbstractWebSocketHandler;
        
        import java.io.IOException;
        import java.util.Map;
        import java.util.concurrent.ConcurrentHashMap;
        
        /**
         * @Description
         * @ClassName WebSocketHandler
         * @Author HYSong
         * @date 2020.04.14 10:08
         */
        public class WebSocketHandler extends AbstractWebSocketHandler {
            /**
             *  存储sessionId和webSocketSession
             *  需要注意的是,webSocketSession没有提供无参构造,不能进行序列化,也就不能通过redis存储
             *  在分布式系统中,要想别的办法实现webSocketSession共享
             */
            private static Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
            private static Map<String, String> userMap = new ConcurrentHashMap<>();
        
            /**
             * webSocket连接创建后调用
             */
            @Override
            public void afterConnectionEstablished(WebSocketSession session) {
                // 获取参数
                String user = String.valueOf(session.getAttributes().get("user"));
                userMap.put(user, session.getId());
                sessionMap.put(session.getId(), session);
            }
        
            /**
             * 接收到消息会调用
             */
            @Override
            public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
                JSONObject jsonObject = JSONObject.parseObject(message.getPayload().toString());
                String content = jsonObject.getString("content");
                String targetAdminId = jsonObject.getString("targetId");
                if("0".equals(targetAdminId)){
                    //  推送给所有人
                    userMap.forEach((key,value)->{
                        try {
                            this.sendMessage(key,content);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
                }else{
                    sendMessage("1", content);
                }
            }
        
            /**
             * 连接出错会调用
             */
            @Override
            public void handleTransportError(WebSocketSession session, Throwable exception) {
                sessionMap.remove(session.getId());
            }
        
            /**
             * 连接关闭会调用
             */
            @Override
            public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
                sessionMap.remove(session.getId());
            }
        
            @Override
            public boolean supportsPartialMessages() {
                return false;
            }
        
            /**
             * 后端发送消息
             */
            public void sendMessage(String user, String message) throws IOException {
                String sessionId = userMap.get(user);
                if (StringUtils.isEmpty(sessionId)) {
                    return;
                }
                WebSocketSession session = sessionMap.get(sessionId);
                if (session == null) {
                    return;
                }
                session.sendMessage(new TextMessage(message));
            }
        }
        
    • 添加拦截器

      • package com.auexpress.cloud.interceptor;
        
        import org.springframework.http.server.ServerHttpRequest;
        import org.springframework.http.server.ServerHttpResponse;
        import org.springframework.http.server.ServletServerHttpRequest;
        import org.springframework.web.socket.WebSocketHandler;
        import org.springframework.web.socket.server.HandshakeInterceptor;
        
        import java.util.Map;
        
        /**
         * @Description
         * @ClassName WebSocketInterceptor
         * @Author HYSong
         * @date 2020.04.14 10:09
         */
        public class WebSocketInterceptor implements HandshakeInterceptor {
            /**
             * handler处理前调用,attributes属性最终在WebSocketSession里,
             * 可能通过webSocketSession.getAttributes().get(key值)获得
             */
            @Override
            public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
                if (request instanceof ServletServerHttpRequest) {
                    ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
                    // 获取请求路径携带的参数
                    String user = serverHttpRequest.getServletRequest().getParameter("user");
                    attributes.put("user", user);
                    return true;
                } else {
                    return false;
                }
            }
        
            @Override
            public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
        
            }
        }
        
        
  • 相关阅读:
    Python自动化开发学习的第十一周----WEB基础(html+css)
    oracle中的rownum详解
    oracle常用函数
    oracle使用exp命令无法导出空表解决方法
    plsql批量执行多个sql脚本示例
    oracle删除表空间和用户
    oracle系统相关表
    SpringMVC常用注解
    RequestMapping注解
    利用plsql只导出某些表,或者视图,或者触发器等
  • 原文地址:https://www.cnblogs.com/bananafish/p/13235144.html
Copyright © 2011-2022 走看看