一、websocket的执行流程
借用b站大佬的图讲解下:分三步走。 二、springboot整合websocket
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.4.4</version>
</dependency>
2.初始化 ServerEndpointExporter
package com.yblue.chat.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.配置ServerEndpoint的方法
package com.yblue.chat.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@ServerEndpoint("/websocket/test")
@Component
public class WebsocketEndpoint {
private static Map<Object, Session> sessionMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
sessionMap.put(session.getId(), session);
log.info("建立连接成功!!!");
log.info("现有的连接数:" + sessionMap.size());
}
@OnClose
public void onClose(Session session) {
try {
sessionMap.remove(session.getId());
session.close();
log.info("关闭连接成功!!!");
log.info("现有的连接数:" + sessionMap.size());
} catch (IOException e) {
log.info("关闭连接失败!!!");
}
}
@OnMessage
public void onMessage(String message) throws IOException {
Collection<Session> sessions = sessionMap.values();
Iterator<Session> iterator = sessions.iterator();
while (iterator.hasNext()) {
iterator.next().getBasicRemote().sendText(message);
}
log.info("实时通讯成功!!!");
}
}
4.可能遇到的场景:
4.1 聊天室(我这个demo不适用,可以去修改,原理懂了都一样),建议可以采用 环信即时通讯 的技术
4.2 就是那些实时监控数据变化的的场景(比如我所在公司有个社区开门记录数据实时更新)
该场景逻辑是:人脸开门,然后后台有个echarts统计的表格实时变化
下面写个小demo测试下:
控制层代码:
package com.yblue.chat.controller;
import com.yblue.chat.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/findById")
public void findById(Integer userId) {
userService.findById(userId);
}
@GetMapping("/update")
public void update(Integer userId) {
userService.update(userId);
}
}
业务层代码:
package com.yblue.chat.service;
import com.yblue.chat.config.WebsocketEndpoint;
import com.yblue.chat.mapper.UserMapper;
import com.yblue.chat.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.websocket.Session;
import java.io.IOException;
@Service
@Transactional
@Slf4j
public class UserService {
@Autowired(required = false)
UserMapper userMapper;
@Autowired
WebsocketEndpoint websocketEndpoint;
public void findById(Integer userId) {
try {
User user = userMapper.selectById(userId);
websocketEndpoint.onMessage(user.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
public void update(Integer userId) {
try {
User user = new User();
user.setUserId(userId);
user.setName("我被改了");
userMapper.updateById(user);
user = userMapper.selectById(userId);
websocketEndpoint.onMessage(user.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.测试
我是综合这个网站(http://coolaf.com/tool/chattest)测试和地址栏测试的,效果如下 5.1建立连接 5.2查询数据 5.3修改数据 5.4关闭窗口刷新界面测试 如下效果,测试结果是会自动调用关闭连接方法(避免了只存不移除导致没有被垃圾回收,造成内存溢出),为了能够被回收,提高系统性能 这只是我对websocket比较浅薄的见解,如果有不对的地方,大佬帮忙指正。
想看更多精彩内容,可以关注我的博客园 我的博客园
|