In some businesses, we need to use long connections. We can use http long connections or websocket. In the framework of springboot as the backend, the technologies that can be borrowed are (netty, websocket)
The version is as follows
Software | Version number |
jdk | 21 |
springboot |
3.1.5 |
springcloud |
2022.0.4 |
Scene recurrence
pom file
<?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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>testDi</artifactId> <version>0.0.1-SNAPSHOT</version> <name>testDi</name> <description>testDi</description> <properties> <java.version>21</java.version> <spring-cloud.version>2022.0.4</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Configuration class
package com.example.testdi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean; @Configuration public class WebsocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxTextMessageBufferSize(8192 * 4); container.setMaxBinaryMessageBufferSize(8192 * 4); return container; } }
rpc class
package com.example.testdi.rpc; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @FeignClient(value = "http://localhost:9090") public interface TestRpc { @GetMapping("/hello") @ResponseBody String hello(); }
websocket class
@Slf4j @Component @ServerEndpoint(value = "/example") public class ExampleWebsocket { @Resource private RedisTemplate<String, Object> redisTemplate; @Resource private TestRpc testRpc; @OnOpen public void open(Session session) { log.info("===============open================="); log.info("redisTemplate: {}", redisTemplate); log.info("testRpc: {}", testRpc); } }
Startup class
@EnableFeignClients @SpringBootApplication public class TestDiApplication { public static void main(String[] args) { SpringApplication.run(TestDiApplication.class, args); } }
Configuration file
spring: data: redis: host: xxx.xxx.xxx.xxx database:xx port: xxxx timeout: xxxx password: xxxxxxxxxxxxxxx server: port: 9090
Effect
You can see that they are all null pointers.
Problem analysis
Is it possible that the bean is not injected into the spring container?
Modify startup class
package com.example.testdi; import jakarta.annotation.Resource; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.ApplicationContext; import java.util.Arrays; import java.util.List; @EnableFeignClients @SpringBootApplication public class TestDiApplication extends SpringBootServletInitializer implements CommandLineRunner { @Resource private ApplicationContext appContext; public static void main(String[] args) { SpringApplication.run(TestDiApplication.class, args); } @Override public void run(String... args) throws Exception { String[] beans = appContext.getBeanDefinitionNames(); Arrays.sort(beans); List<String> list = Arrays.stream(beans).filter(ele -> ele.contains("TestRpc") || ele.contains("redisTemplate")).toList(); for (String bean : list) { System.out.println(bean + " of Type :: " + appContext.getBean(bean).getClass()); } } }
View console
It was found that this was not the case
Not obtained/wrong method of acquisition
Solution
Use auxiliary classes
package com.example.testdi.utils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class ApplicationHelper implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ApplicationHelper.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } public static Object getBean(String beanName) { return applicationContext.getBean(beanName); } }
Modify websocket code
package com.example.testdi.websocket; import com.example.testdi.rpc.TestRpc; import com.example.testdi.utils.ApplicationHelper; import jakarta.annotation.Resource; import jakarta.websocket.OnOpen; import jakarta.websocket.Session; import jakarta.websocket.server.ServerEndpoint; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @Slf4j @Component @ServerEndpoint(value = "/example") public class ExampleWebsocket { private RedisTemplate<String, Object> redisTemplate= (RedisTemplate<String, Object>) ApplicationHelper.getBean("redisTemplate"); private TestRpc testRpc= (TestRpc) ApplicationHelper.getBean("com.example.testdi.rpc.TestRpc"); @OnOpen public void open(Session session) { log.info("===============open================="); log.info("redisTemplate: {}", redisTemplate); log.info("testRpc: {}", testRpc); } }
Effect
Some questions
How to test the websocket interface
Here are 2 recommended ones, one is postman and the other is website
postman
Now you can start testing
Website
Here is a recommended test website for testing, supporting ws/wss
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Network Skill TreeHomepageOverview 42305 people are learning the system