SpringCloud Gateway integrates WebSocket service

As a programmer, I have been working for 7 or 8 years. This is my first time writing an article. I am really ashamed. I used to be Baidu and Google because of my work needs, but I didn't want to calm down and study the principles and source code by myself, so I am still a rookie now. . .

All right. Closer to home, this practice is based on nacos as the configuration and registration center. You can go to the official website of nacos. Although this component has a bug recently, it is undeniable that its function is really powerful. Official website address: https://nacos.io/zh-cn/

The project uses jdk1.8 for development. Use maven for jar package management, divided into many module sub-projects, including common modules for basic services (Redis, MongoDB, RocketMQ component integration, UUID, DateUtil, encryption and decryption tools, etc.), service provider demo-provider, and service provider For consumer demo-consumer, websocket service, etc., the structure of the demo project is as follows:

The POM information of the Parent project of all sub-modules is as follows. Although I have cited zipkin and sleuth, the related functions have not been implemented yet. The integration will be implemented later. I will post the article again. If you don't need it, you can delete it yourself:

ParentPOM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>XX.XX</groupId>
    <artifactId>platform</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>platform</name>
    <description>XX中台服务</description>
    <packaging>pom</packaging>
    <properties>
        <spring-boot.version>2.0.4.RELEASE</spring-boot.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>
    <modules>
        <module>common</module>
        <module>gateway</module>
        <module>servers/demo-provider</module>
        <module>servers/demo-consumer</module>
        <module>servers/taskinput</module>
        <module>servers/imchat</module>
    </modules>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-security</artifactId>-->
<!--        </dependency>-->
        <!-- 引入Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

The following is the GateWay content:

POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>XX.XX</groupId>
        <artifactId>platform</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>XX.XX.platform</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>XX中台服务网关</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>0.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>XX.XX.platform</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>../../docker/XX-gateway</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.smartgis.GatewayStarterApplication</mainClass>
                    <layout>ZIP</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 GateWay configuration file information (application.yml): 

server:
  port: 8001
spring:
  application:
    name: demo-gateway
  cloud:
    nacos:
      discovery:
        namespace: 0ee7047e-90db-45d9-a85c-b3aa206aba5b
        server-addr: 127.0.0.1:8848
    gateway:
#      此处不注掉,会导致gateway转发websocket服务的时候出现自动断开的情况,报504错误
#      default-filters:
#        - name: Hystrix
#          args:
#            name: myfallback
#            fallbackUri: forward:/defaultfallback
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods: "*"
#      此处不注掉,会导致gateway转发websocket服务的时候出现自动断开的情况,报504错误
#      discovery:
#        locator:
#          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: taskinput
          uri: lb://taskinput
          order: 0
          predicates:
            - Path=/taskinput/**
          filters:
            - StripPrefix=1 #去掉前缀,具体实现参考StripPrefixGatewayFilterFactory
            - AddResponseHeader=X-Response-Default-Foo, Default-Bar
            - name: Hystrix
              args:
                name: myfallback
                fallbackUri: forward:/defaultfallback
        - id: demo-provider
          uri: lb://demo-provider
          order: 0
          predicates:
            - Path=/provider/**
          filters:
            - StripPrefix=1 #去掉前缀,具体实现参考StripPrefixGatewayFilterFactory
            - AddResponseHeader=X-Response-Default-Foo, Default-Bar
        - id: demo-consumer
          uri: lb://demo-consumer
          order: 0
          predicates:
            - Path=/consumer/**
          filters:
            - StripPrefix=1 #去掉前缀,具体实现参考StripPrefixGatewayFilterFactory
            - AddResponseHeader=X-Response-Default-Foo, Default-Bar
        #实际的超时时间是(ReadTimeout+ConnectTimeout)*(MaxAutoRetries+1)*(MaxAutoRetriesNextServer+1)
        #如果MaxAutoRetries和MaxAutoRetriesNextServer都设为0,那么实际超时就是(ReadTimeout+ConnectTimeout)了
        - id: imchat
          uri: lb:ws://imchat
          predicates:
            - Path=/ws/**
          filters:
            - StripPrefix=1
#        - id: imchat
#          uri: lb://imchat
#          predicates:
#            - Path=/ws/info/**
#        - id: imchat
#          uri: lb:ws://imchat
#          predicates:
#            - Path=/ws/**
        - id: bulletscreen
          uri: lb://bullet
          predicates:
            - Path=/bullet/info/**
        - id: bulletscreen
          uri: lb:ws://bullet
          predicates:
            - Path=/bullet/**
ribbon:
  eureka:
    enabled: false
  eager-load:
    enabled: true #饥饿加载,系统启动时创建好ribbon客户端而不是在使用时去创建
  ConnectTimeout: 2000 #单位ms,请求连接超时时间
  ReadTimeout: 4000 #单位ms,请求处理的超时时间
  OkToRetryOnAllOperations: false #对所有操作请求都进行重试
  MaxAutoRetriesNextServer: 0 #切换实例的重试次数
  MaxAutoRetries: 0 #对当前实例的重试次数
  ServerListRefreshInterval: 2000 #Interval to refresh the server list from the source
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule
management:
  endpoints:
    web:
      exposure:
        include: refresh

 Hystrix circuit breaker:

import XX.XX.platform.common.base.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DefaultHystrixController {

    @RequestMapping("/defaultfallback")
    @ResponseBody
    public Result defaultFallBack()
    {
        return Result.createFail("服务不可用,请稍后重试。");
    }
}

Startup class:

@SpringBootApplication
@EnableDiscoveryClient
@RefreshScope
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

}

The following is IMChat service:

Why is it called IMChat and not websocket, because at first I thought of websocket service, I wanted to build IM service, and then combined with MQ service, I thought that the front-end and back-end overseas Chinese could be connected through the websocket service, and the message was forwarded through MQ to achieve distribution The purpose of the style, from the perspective of the demo service, this idea seems feasible, but there are any problems in the follow-up, because my ability is limited, and it is not clear. Please enlighten me.

POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>XX.XX</groupId>
      <artifactId>platform</artifactId>
      <version>0.0.1-SNAPSHOT</version>
   </parent>
   <groupId>XX.XX.platform</groupId>
   <artifactId>imchat</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>imchat</name>
   <description>聊天/推送服务</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         <version>0.2.2.RELEASE</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
         <version>0.2.1.RELEASE</version>
      </dependency>
      <!--web 组件 -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-websocket</artifactId>
      </dependency>
      <dependency>
         <groupId>XX.XX.platform</groupId>
         <artifactId>common</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
   </dependencies>

   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>

   <build>
      <finalName>../../docker/imchat-server</finalName>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

Configuration file application.yml

server:
  port: 1999
spring:
  application:
    name: imchat
  cloud:
    nacos:
      discovery:
        namespace: 0ee7047e-90db-45d9-a85c-b3aa206aba5b
        server-addr: 127.0.0.1:8848
  data:
    mongodb:
      uri: mongodb://root:[email protected]:27017/bhplatform?maxpoolsize=10&minpoolsize=1&maxidletimems=600000&maxlifetimems=1800000
  cache:
    redis:
      time-to-live: 60s
    type: redis
  #redis配置
  redis:
    cluster:
      nodes: 127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6383,127.0.0.1:6384
    timeout: 6000ms
    lettuce:
      pool:
        max-active: 8
        max-wait: -1ms
        max-idle: 8
        min-idle: 0
    database: 0
  jackson:
    time-zone: GMT+8
apache:
  rocketmq:
    consumer:
      pushConsumer: XXPushConsumer
    producer:
      producerGroup: XX
    namesrvAddr: 127.0.0.1:9876
logging:
  path: /java-log
  level:
    root: info
management:
  endpoints:
    web:
      exposure:
        include: refresh

 MyWebSocketHandler

import com.alibaba.fastjson.JSONObject;
import XX.XX.common.DateUtil;
import XX.XX.common.base.BaseCode;
import XX.XX.common.cache.redis.RedisService;
import XX.XX.entity.IM.IMChatMessage;
import XX.XX.entity.IM.IMChatRequest;
import XX.XX.entity.IM.IMChatResponse;
import XX.XX.common.mq.producer.Producer;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.*;
import com.XX.XX.taskinput.entity.UserVO;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class MyWebSocketHandler  implements WebSocketHandler {

    @Autowired
    private RedisService redisService;

    @Autowired
    private Producer rocketProducer;

    /**
     * NameServer 地址
     */
    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;

    private static final ConcurrentHashMap map = new ConcurrentHashMap();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        log.info("connect websocket successful!");
        IMChatMessage chat = new IMChatMessage();
        chat.setGmtCreat(DateUtil.getCurrentDateTime());
        chat.setData(session.getId());
        chat.setType(BaseCode.SINGLELOGIN);

        String userid = session.getAttributes().get(BaseCode.USERID).toString();
        log.info(userid);
        chat.setFrom(userid);
        sendMessageToUser(userid, chat);
        WebSocketSession sessiono = (WebSocketSession) map.get(userid + BaseCode.SESSION);
        if (sessiono != null) {
            log.info("close original session-start");
            try {
                sessiono.close();
            } catch (IOException e) {
                log.info("close original session failed");
            }

        }
        DefaultMQPushConsumer consumero = (DefaultMQPushConsumer) map.get(userid + BaseCode.CONSUMER);
        if (consumero != null) {
            log.info("close original consumer-start");
            consumero.shutdown();
        }


        //todo 开启线程,读取群和好友消息
        //需要执行的代码
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(userid);
        consumer.setNamesrvAddr(namesrvAddr);
        try {
            // 订阅PushTopic下Tag为push的消息,都订阅消息
            consumer.subscribe(BaseCode.IMCHAT, userid);
            // 程序第一次启动从消息队列头获取数据
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            //可以修改每次消费消息的数量,默认设置是每次消费一条
            consumer.setConsumeMessageBatchMaxSize(1);
            //在此监听中消费信息,并返回消费的状态信息
            consumer.registerMessageListener((MessageListenerOrderly) (list, consumeOrderlyContext) -> {
                if (!session.isOpen()) {
                    consumer.shutdown();
                    return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
                }
                for (MessageExt messageExt : list) {
                    try {
                        session.sendMessage(new TextMessage(new String(messageExt.getBody(), "UTF-8")));
                        log.info("消费响应:MsgId:" + messageExt.getMsgId() + ",msgBody:" + new String(messageExt.getBody(), "UTF-8") + ",tag:" + messageExt.getTags() + ",topic:" + messageExt.getTopic());
                    } catch (IOException e) {
                        return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
                    }
                }
                return ConsumeOrderlyStatus.SUCCESS;
            });
            log.info("start consumer");
            consumer.start();
            map.put(userid + BaseCode.CONSUMER, consumer);
            map.put(userid + BaseCode.SESSION, session);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("start consumer exception");
        }

    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message){
        log.info("handle message start");
        try {
            IMChatRequest chat = JSONObject.parseObject((String) message.getPayload(), IMChatRequest.class);
            UserVO user = (UserVO) redisService.get(session.getAttributes().get(BaseCode.TOKEN).toString());
            if (user == null) {
                session.sendMessage(new TextMessage(new IMChatResponse(BaseCode.FAILCODE, BaseCode.FAILSSMSG, "token is invalid").toString()));
                session.close();
            } else {
                user.setToken("");
                IMChatMessage chatMessage = new IMChatMessage();
                chatMessage.setGmtCreat(DateUtil.getCurrentDateTime());
                chatMessage.setData(chat.getData());
                chatMessage.setType(chat.getType());
                chatMessage.setFrom(user);
                if (chat.getTouserid().length > 0) {
                    for (String toid : chat.getTouserid()) {
                        sendMessageToUser(toid, chatMessage);
                    }
                }
            }
        } catch (Exception e) {
            log.error("e", e);
        }

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("handle message start");
        if (session.isOpen()) {
            session.close();
        }
        log.error("connect error", exception);
        String userid = session.getAttributes().get(BaseCode.USERID).toString();
        DefaultMQPushConsumer consumer = (DefaultMQPushConsumer) map.get(userid + BaseCode.CONSUMER);
        consumer.shutdown();
        map.remove(userid + BaseCode.CONSUMER);
        map.remove(userid + BaseCode.SESSION);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
        log.error("connection closed: " + closeStatus);
        String userid = session.getAttributes().get(BaseCode.USERID).toString();
        DefaultMQPushConsumer consumer = (DefaultMQPushConsumer) map.get(userid + BaseCode.CONSUMER);
        consumer.shutdown();
        map.remove(userid + BaseCode.CONSUMER);
        map.remove(userid + BaseCode.SESSION);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送信息给指定用户
     *
     * @param clientId
     * @param message
     * @return
     */
    public boolean sendMessageToUser(String clientId, IMChatMessage message) {
        log.info("to userid:" + clientId + ",tomessage:" + message.toString());
        rocketProducer.sendMsg(BaseCode.IMCHAT, clientId, message.toString());
        return true;
    }

}

WebSocketInterceptor 

import XX.XX.common.base.BaseCode;
import XX.XX.platform.common.cache.redis.RedisService;
import XX.XX.platform.taskinput.entity.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

@Slf4j
@Service
public class WebSocketInterceptor implements HandshakeInterceptor {
    @Autowired
    private RedisService redisService;

    //在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置WebSocketSession的属性
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes){
        if (request instanceof ServletServerHttpRequest) {
            String uri = request.getURI().toString();
            String token = uri.substring(uri.lastIndexOf("/")+1);
            UserVO user = (UserVO) redisService.get(token);
            log.info("current token is:"+token);
            if(user==null)
            {
                return false;
            }
            attributes.put(BaseCode.TOKEN,token);
            attributes.put(BaseCode.USERID,user.getUserid());
            log.info(user.getUserid());
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
        log.info("coming webSocketInterceptor afterHandshake method...");
    }

}

WebSocketConfig 

import XX.XX.platform.imchat.interceptor.WebSocketInterceptor;
import XX.XX.platform.imchat.listener.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
 * 首先注入一个ServerEndpointExporterBean,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @Autowired
    private WebSocketInterceptor webSocketInterceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, "/imchat/{TOKEN}")
                .setAllowedOrigins("*")
                .addInterceptors(webSocketInterceptor);
    }
}

ImchatApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan({"XX.XX.platform"})
public class ImchatApplication {

   public static void main(String[] args) {
      SpringApplication.run(ImchatApplication.class, args);
   }

}

effect:

The above is all the code of this demo. If it involves other modules, you can leave a message if you need it. In addition, I am very grateful to the author of hasor @哈库纳玛塔塔 for your help and support, and I also recommend it to everyone. The open source framework dataway, we are using recently, very easy to use, highly recommended, attach the official website: https://www.hasor.net/doc/

 

Guess you like

Origin blog.csdn.net/weixin_40261814/article/details/113242415