1.新建一个springboot项目,导入pom文件websocket依赖的jar
<!-- 添加webSocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.新建一个配置类,用于开启websocket支持
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3.新建一个用于客户端访问的websocket连接类
@Component
@Service
@ServerEndpoint("/api/websocket/{sid}")
public class WebSocketServerService {
//当前在线连接数
private static int onlineCount = 0;
//存放每个客户端对应的MyWebsocket对象
private static Map<String, WebSocketServerService> copyOnWriteArraySet = new HashMap();
private Session session;
//接收sid
private String sid = "";
//实现服务器主动推送
public void sendMsg(String msg) {
try {
this.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
//连接建立成功后会立即调用@OnOpen标注的方法
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
this.session = session;
copyOnWriteArraySet.put(sid, this);
this.sid = sid;
WebSocketServerService.onlineCount++;
//推送数据
sendMsg("连接成功");
System.out.println("有新的窗口开始监听" + sid + ",当前在线人数为:" + this.onlineCount);
}
//连接关闭时会自动调用的方法
@OnClose
public void onClose() {
//移除需要关闭的对象
copyOnWriteArraySet.remove(this);
WebSocketServerService.onlineCount--;
System.out.println("释放的sid为:" + sid);
System.out.println("有一个连接关闭!当前在线人数为" + WebSocketServerService.onlineCount);
}
//发生错误时,会自动调用@OnError标注的方法进行异常处理
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
//这边是我们主要的业务方法,是服务器端给客户端发信息的思路,在Controller层进行调用,主要是实现在接口被调用时,对目前在线的客户端进行数据推送。
public static void sengInfo(String msg, @PathVariable("sid") String sid) {
System.out.println("推送信息到窗口" + sid + "推送内容:" + msg);
//sid不为空就将匹配的信息发给相应客户端
if (!StringUtils.isEmpty(sid)) copyOnWriteArraySet.get(sid).sendMsg(msg);
//sid是空的,所有的客户端都发,遍历map中所有的对象,并发送信息
if (StringUtils.isEmpty(sid)) copyOnWriteArraySet.forEach((key, value) -> value.sendMsg(msg));
}
//收到客户端消息时触发。处理客户端通过这个websocket方法提供的访问地址(eg:ws://localhost:8080/api/websocket/123)推送过来的数据.。常见于前端调用,进行数据推送。
@OnMessage
public void onMsg(String info, Session session) {
//这个方法没什么暖用,之前的@Open方法已经将当前方法的session存到集合中了
Set<WebSocketServerService> collect = copyOnWriteArraySet.values().stream().filter(a -> a.session.getId().equals(session.getId())).collect(Collectors.toSet());
//给所有已经连接的客户端进行消息群发
copyOnWriteArraySet.forEach((key, value) -> copyOnWriteArraySet.get(value.sid).sendMsg(info));
//获取服务端到客户端的通道并发送信息
collect.forEach(a -> copyOnWriteArraySet.get(a.sid).sendMsg("服务器收到了信息,并把信息返回给你" + info));
System.out.println("服务器收到了" + info);
}
}
4.controller层
//由于@PathVariable 不能为空,这边约定传1的时候,默认sid为空
@RestController
@RequestMapping("/api/webSocketLink")
public class WebSocketController {
@GetMapping("sendInfo/{sid}")
@ApiOperation("发送信息")
public Map sendSocket(@PathVariable String sid,String msg){
if("1".equals(sid)){
sid="";
}
Map<String ,Object> result = new HashMap<>();
WebSocketServerService.sengInfo(msg,sid);
result.put("sid",sid);
result.put("msg",msg);
return result;
}
}
效果展示:
连接:
第二个连接
第三连接
服务器推送数据给12345
给所有客户端推送信息
断开连接
以上就是常规的websocket使用了。