注意一点 : 适用于通过内置Jetty容器或者外部Jetty容器运行项目的情况
文章目录
现在开始
1. 创建SpringBoot项目
开发工具 :
IDEA2019.3
JDK1.8
点击next
填写对应的内容,继续点击next
什么都不选,继续点击next
点击finish构建
2. POM
打开pom.xml, 添加以下依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去除内置tomcat -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--使用jetty服务器启动-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
3. 创建 JettyWebsocketServlet类
配置websocket
public class JettyWebsocketServlet extends WebSocketServlet {
public static final long TIME_OUT = 1800000;
@Override
public void configure(WebSocketServletFactory webSocketServletFactory) {
// 设置连接多久不活跃自动断开
webSocketServletFactory.getPolicy().setIdleTimeout(TIME_OUT);
// 注册
webSocketServletFactory.register(WebSocketService.class);
}
}
4. 创建 WebSocketService
执行通信的真正操作
/**
* @author : lyp
* @date : 2022/1/8 12:13
*/
@WebSocket
@Slf4j
@Component
public class WebSocketService {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static int onlineCount = 0;
/**
* concurrent包的线程安全map,用来存放每个客户端对应的MyWebSocket对象。
*/
private static Set<WebSocketService> set = new CopyOnWriteArraySet<>();
private Session session;
@OnWebSocketConnect
public void onConnect(Session session) {
this.session = session;
set.add(this);
System.out.println(set);
addOnlineCount();
log.info("连接成功!当前连接人数为 : " + getOnlineCount());
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
set.remove(this);
System.out.println(set);
subOnlineCount();
log.info("当前在线人数为:" + getOnlineCount());
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getRemote().sendString(message);
}
public static synchronized void addOnlineCount() {
WebSocketService.onlineCount++;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
public static synchronized void subOnlineCount() {
WebSocketService.onlineCount--;
}
@OnWebSocketMessage
public void onMessage(String msg) {
log.info("接受信息: {}", msg);
try {
// 发送信息出去
session.getRemote().sendString("后端返回信息----》" + msg);
} catch (Throwable t) {
t.printStackTrace();
log.error("信息发送异常:{}", t.getMessage());
}
}
}
5. 创建JettyWebsocketConfig配置类
交给spring管理
@Configuration
public class JettyWebsocketConfig {
@Bean
public ServletRegistrationBean<HttpServlet> jettyWebsocket1() {
ServletRegistrationBean<HttpServlet> registrationBean = new ServletRegistrationBean<>();
// 指定JettyWebsocketServlet
registrationBean.setServlet(new JettyWebsocketServlet());
// 指定servlet处理的请求地址
registrationBean.addUrlMappings("/websocket");
return registrationBean;
}
}
6. 设置端口
在application.properties中设置内嵌容器的端口号
server.port=12499
7. 连接测试
启动springboot项目
我使用的是postman进行测试, 创建websocket测试页, 输入连接地址
点击旁边的 connect , 显示连接成功了
在中间的 New Message 框中输入文字点击右下角 Send 进行通信
可以接受到服务器返回的信息
8. 后端主动通信
为模拟真实效果,我们起一个定时器来向前端发送消息
在启动类上贴 @EnableScheduling 注解来开启定时任务支持
在WebSocketService类中新增方法
/**
* 实现后端跟前端建立连接后主动向前端发送消息 -> 两秒一次
*/
@Scheduled(cron = "0/2 * * * * ?")
public void activeSendMessage(){
//向所有建立了连接的前端发送消息
for (WebSocketService service : set) {
try {
service.session.getRemote().sendString("后端主动发送消息啦~~");
} catch (IOException e) {
log.error(e.getMessage(),e);
}
}
}
重新进行测试
可以看到,连接成功后,每隔两秒后台服务都会向前台发送消息
通过一个小小的demo实现了服务器向前台的主动通信, 还有一种可以向指定的前台发送消息没有实现, 以后有机会再补上
真实项目开发中,可以通过这种进行简单的连接通信,也可以使用一些成熟的开源第三方组件进行主动通信,功能更强大
通过springboot内嵌tomcat容器集成websocket更加简单,下期实现
bye~