feat(视频):

视频初步
This commit is contained in:
Guwan 2024-12-08 19:25:20 +08:00
parent 92ce67245d
commit 12cfe0a184
12 changed files with 423 additions and 384 deletions

View File

@ -229,13 +229,6 @@
<artifactId>spring-boot-starter-websocket</artifactId> <artifactId>spring-boot-starter-websocket</artifactId>
</dependency> </dependency>
<!-- SRS Java SDK -->
<dependency>
<groupId>com.github.ossrs</groupId>
<artifactId>srs-sdk</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Netty --> <!-- Netty -->
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
@ -245,7 +238,7 @@
<!-- Easy-Es --> <!-- Easy-Es -->
<dependency> <dependency>
<groupId>cn.easyes</groupId> <groupId>cn.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId> <artifactId>easy-es-boot-starter</artifactId>
<version>1.1.1</version> <version>1.1.1</version>
</dependency> </dependency>

View File

@ -1,83 +1,83 @@
package com.guwan.backend.client; //package com.guwan.backend.client;
//
import lombok.Data; //import lombok.Data;
import lombok.RequiredArgsConstructor; //import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; //import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity; //import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate; //import org.springframework.web.client.RestTemplate;
//
@Slf4j //@Slf4j
@Component //@Component
@RequiredArgsConstructor //@RequiredArgsConstructor
public class SrsClient { //public class SrsClient {
//
private final RestTemplate restTemplate; // private final RestTemplate restTemplate;
//
@Value("${srs.server.url}") // @Value("${srs.server.url}")
private String srsServerUrl; // private String srsServerUrl;
//
/** // /**
* 开始录制 // * 开始录制
*/ // */
public void startRecord(String streamKey, RecordConfig config) { // public void startRecord(String streamKey, RecordConfig config) {
String url = String.format("%s/api/v1/streams/%s/recording/start", srsServerUrl, streamKey); // String url = String.format("%s/api/v1/streams/%s/recording/start", srsServerUrl, streamKey);
try { // try {
ResponseEntity<String> response = restTemplate.postForEntity(url, config, String.class); // ResponseEntity<String> response = restTemplate.postForEntity(url, config, String.class);
if (!response.getStatusCode().is2xxSuccessful()) { // if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("开始录制失败: " + response.getBody()); // throw new RuntimeException("开始录制失败: " + response.getBody());
} // }
} catch (Exception e) { // } catch (Exception e) {
log.error("开始录制失败", e); // log.error("开始录制失败", e);
throw new RuntimeException("开始录制失败", e); // throw new RuntimeException("开始录制失败", e);
} // }
} // }
//
/** // /**
* 停止录制 // * 停止录制
*/ // */
public void stopRecord(String streamKey) { // public void stopRecord(String streamKey) {
String url = String.format("%s/api/v1/streams/%s/recording/stop", srsServerUrl, streamKey); // String url = String.format("%s/api/v1/streams/%s/recording/stop", srsServerUrl, streamKey);
try { // try {
ResponseEntity<String> response = restTemplate.postForEntity(url, null, String.class); // ResponseEntity<String> response = restTemplate.postForEntity(url, null, String.class);
if (!response.getStatusCode().is2xxSuccessful()) { // if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("停止录制失败: " + response.getBody()); // throw new RuntimeException("停止录制失败: " + response.getBody());
} // }
} catch (Exception e) { // } catch (Exception e) {
log.error("停止录制失败", e); // log.error("停止录制失败", e);
throw new RuntimeException("停止录制失败", e); // throw new RuntimeException("停止录制失败", e);
} // }
} // }
//
/** // /**
* 获取流信息 // * 获取流信息
*/ // */
public StreamInfo getStreamInfo(String streamKey) { // public StreamInfo getStreamInfo(String streamKey) {
String url = String.format("%s/api/v1/streams/%s", srsServerUrl, streamKey); // String url = String.format("%s/api/v1/streams/%s", srsServerUrl, streamKey);
try { // try {
ResponseEntity<StreamInfo> response = restTemplate.getForEntity(url, StreamInfo.class); // ResponseEntity<StreamInfo> response = restTemplate.getForEntity(url, StreamInfo.class);
return response.getBody(); // return response.getBody();
} catch (Exception e) { // } catch (Exception e) {
log.error("获取流信息失败", e); // log.error("获取流信息失败", e);
throw new RuntimeException("获取流信息失败", e); // throw new RuntimeException("获取流信息失败", e);
} // }
} // }
//
@Data // @Data
public static class RecordConfig { // public static class RecordConfig {
private String format = "flv"; // 录制格式 // private String format = "flv"; // 录制格式
private String filePath; // 文件路径 // private String filePath; // 文件路径
} // }
//
@Data // @Data
public static class StreamInfo { // public static class StreamInfo {
private String streamId; // 流ID // private String streamId; // 流ID
private String clientId; // 客户端ID // private String clientId; // 客户端ID
private String ip; // 客户端IP // private String ip; // 客户端IP
private Long startTime; // 开始时间 // private Long startTime; // 开始时间
private String status; // 状态 // private String status; // 状态
private Long bytesIn; // 输入字节数 // private Long bytesIn; // 输入字节数
private Long bytesOut; // 输出字节数 // private Long bytesOut; // 输出字节数
} // }
} //}

View File

@ -1,82 +1,82 @@
package com.guwan.backend.controller; //package com.guwan.backend.controller;
//
import com.guwan.backend.entity.LiveRoom; //import com.guwan.backend.entity.LiveRoom;
import com.guwan.backend.entity.LiveRoomDTO; //import com.guwan.backend.entity.LiveRoomDTO;
import com.guwan.backend.service.LiveService; //import com.guwan.backend.service.LiveService;
import com.guwan.backend.util.Result; //import com.guwan.backend.util.Result;
import com.guwan.backend.util.SecurityUtil; //import com.guwan.backend.util.SecurityUtil;
import lombok.RequiredArgsConstructor; //import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; //import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Operation; //import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema; //import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.security.SecurityRequirement; //import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag; //import io.swagger.v3.oas.annotations.tags.Tag;
//
@Slf4j //@Slf4j
@Tag(name = "直播管理", description = "直播相关接口") //@Tag(name = "直播管理", description = "直播相关接口")
@RestController //@RestController
@RequestMapping("/api/live") //@RequestMapping("/api/live")
@RequiredArgsConstructor //@RequiredArgsConstructor
public class LiveController { //public class LiveController {
//
private final LiveService liveService; // private final LiveService liveService;
private final SecurityUtil securityUtil; // private final SecurityUtil securityUtil;
//
@Operation(summary = "创建直播间") // @Operation(summary = "创建直播间")
@SecurityRequirement(name = "bearer-jwt") // @SecurityRequirement(name = "bearer-jwt")
@PostMapping("/room") // @PostMapping("/room")
public Result<LiveRoom> createLiveRoom(@RequestBody LiveRoomDTO dto) { // public Result<LiveRoom> createLiveRoom(@RequestBody LiveRoomDTO dto) {
try { // try {
return Result.success(liveService.createLiveRoom(dto)); // return Result.success(liveService.createLiveRoom(dto));
} catch (Exception e) { // } catch (Exception e) {
log.error("创建直播间失败", e); // log.error("创建直播间失败", e);
return Result.error(e.getMessage()); // return Result.error(e.getMessage());
} // }
} // }
//
@Operation(summary = "开始直播") // @Operation(summary = "开始直播")
@SecurityRequirement(name = "bearer-jwt") // @SecurityRequirement(name = "bearer-jwt")
@PostMapping("/room/{id}/start") // @PostMapping("/room/{id}/start")
public Result<Void> startLive(@PathVariable Long id) { // public Result<Void> startLive(@PathVariable Long id) {
try { // try {
// 检查权限 // // 检查权限
checkPermission(id); // checkPermission(id);
liveService.startLive(id); // liveService.startLive(id);
return Result.success(); // return Result.success();
} catch (Exception e) { // } catch (Exception e) {
log.error("开始直播失败", e); // log.error("开始直播失败", e);
return Result.error(e.getMessage()); // return Result.error(e.getMessage());
} // }
} // }
//
@Operation(summary = "结束直播") // @Operation(summary = "结束直播")
@SecurityRequirement(name = "bearer-jwt") // @SecurityRequirement(name = "bearer-jwt")
@PostMapping("/room/{id}/end") // @PostMapping("/room/{id}/end")
public Result<Void> endLive(@PathVariable Long id) { // public Result<Void> endLive(@PathVariable Long id) {
try { // try {
// 检查权限 // // 检查权限
checkPermission(id); // checkPermission(id);
liveService.endLive(id); // liveService.endLive(id);
return Result.success(); // return Result.success();
} catch (Exception e) { // } catch (Exception e) {
log.error("结束直播失败", e); // log.error("结束直播失败", e);
return Result.error(e.getMessage()); // return Result.error(e.getMessage());
} // }
} // }
//
/** // /**
* 检查权限 // * 检查权限
*/ // */
private void checkPermission(Long roomId) { // private void checkPermission(Long roomId) {
LiveRoom room = liveService.getLiveRoom(roomId); // LiveRoom room = liveService.getLiveRoom(roomId);
if (room == null) { // if (room == null) {
throw new IllegalArgumentException("直播间不存在"); // throw new IllegalArgumentException("直播间不存在");
} // }
//
Long currentUserId = securityUtil.getCurrentUserId(); // Long currentUserId = securityUtil.getCurrentUserId();
if (!room.getUserId().equals(currentUserId)) { // if (!room.getUserId().equals(currentUserId)) {
throw new IllegalStateException("无权操作此直播间"); // throw new IllegalStateException("无权操作此直播间");
} // }
} // }
} //}

View File

@ -27,12 +27,12 @@ public class VideoController {
// @SecurityRequirement(name = "bearer-jwt") // @SecurityRequirement(name = "bearer-jwt")
@PostMapping("/upload") @PostMapping("/upload")
public Result<VideoDTO> uploadVideo( public Result<VideoDTO> uploadVideo(
@Parameter(description = "视频文件") @RequestParam("file") MultipartFile file, @Parameter(description = "视频文件") @RequestParam("fileUrl") String fileUrl,
@Parameter(description = "视频标题") @RequestParam("title") String title, @Parameter(description = "视频标题") @RequestParam("title") String title,
@Parameter(description = "视频描述") @RequestParam("description") String description, @Parameter(description = "视频描述") @RequestParam("description") String description,
@Parameter(description = "视频标签,多个用逗号分隔") @RequestParam(value = "tags", required = false) String tags) { @Parameter(description = "视频标签,多个用逗号分隔") @RequestParam(value = "tags", required = false) String tags) {
try { try {
VideoDTO video = videoService.uploadVideo(file, title, description, tags); VideoDTO video = videoService.uploadVideo(fileUrl, title, description, tags);
return Result.success(video); return Result.success(video);
} catch (Exception e) { } catch (Exception e) {
log.error("上传视频失败", e); log.error("上传视频失败", e);

View File

@ -1,3 +1,9 @@
package com.guwan.backend.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data @Data
public class LiveMessage { public class LiveMessage {
private String type; // 消息类型CHAT-聊天GIFT-礼物LIKE-点赞ENTER-进入LEAVE-离开 private String type; // 消息类型CHAT-聊天GIFT-礼物LIKE-点赞ENTER-进入LEAVE-离开

View File

@ -1,3 +1,10 @@
package com.guwan.backend.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data @Data
@TableName("live_room") @TableName("live_room")
public class LiveRoom { public class LiveRoom {

View File

@ -1,120 +1,132 @@
@Slf4j //package com.guwan.backend.service;
@Service //
@RequiredArgsConstructor //import com.guwan.backend.client.SrsClient;
public class LiveService { //import com.guwan.backend.dto.live.LiveRoomDTO;
//import com.guwan.backend.entity.LiveRoom;
private final LiveRoomMapper liveRoomMapper; //import com.guwan.backend.mapper.LiveRoomMapper;
private final SrsClient srsClient; //import com.guwan.backend.util.SecurityUtil;
private final SecurityUtil securityUtil; //import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
/** //import org.springframework.beans.BeanUtils;
* 创建直播间 //import org.springframework.stereotype.Service;
*/ //
public LiveRoom createLiveRoom(LiveRoomDTO dto) { //@Slf4j
// 获取当前用户 //@Service
Long userId = securityUtil.getCurrentUserId(); //@RequiredArgsConstructor
String username = securityUtil.getCurrentUsername(); //public class LiveService {
if (userId == null) { //
throw new IllegalStateException("用户未登录"); // private final LiveRoomMapper liveRoomMapper;
} // private final SrsClient srsClient;
// private final SecurityUtil securityUtil;
LiveRoom room = new LiveRoom(); //
BeanUtils.copyProperties(dto, room); // /**
// * 创建直播间
// 设置用户信息 // */
room.setUserId(userId); // public LiveRoom createLiveRoom(LiveRoomDTO dto) {
room.setUsername(username); // // 获取当前用户
// Long userId = securityUtil.getCurrentUserId();
// 生成推流密钥 // String username = securityUtil.getCurrentUsername();
String streamKey = generateStreamKey(); // if (userId == null) {
room.setStreamKey(streamKey); // throw new IllegalStateException("用户未登录");
// }
// 生成推流地址 //
String rtmpUrl = generateRtmpUrl(streamKey); // LiveRoom room = new LiveRoom();
room.setRtmpUrl(rtmpUrl); // BeanUtils.copyProperties(dto, room);
//
// 生成播放地址 // // 设置用户信息
String hlsUrl = generateHlsUrl(streamKey); // room.setUserId(userId);
room.setHlsUrl(hlsUrl); // room.setUsername(username);
//
room.setStatus("PREPARING"); // // 生成推流密钥
room.setOnlineCount(0); // String streamKey = generateStreamKey();
room.setLikeCount(0); // room.setStreamKey(streamKey);
//
liveRoomMapper.insert(room); // // 生成推流地址
return room; // String rtmpUrl = generateRtmpUrl(streamKey);
} // room.setRtmpUrl(rtmpUrl);
//
/** // // 生成播放地址
* 开始直播 // String hlsUrl = generateHlsUrl(streamKey);
*/ // room.setHlsUrl(hlsUrl);
public void startLive(Long roomId) { //
LiveRoom room = liveRoomMapper.selectById(roomId); // room.setStatus("PREPARING");
room.setStatus("LIVING"); // room.setOnlineCount(0);
liveRoomMapper.updateById(room); // room.setLikeCount(0);
//
// 开始录制 // liveRoomMapper.insert(room);
startRecording(room.getStreamKey()); // return room;
} // }
//
/** // /**
* 结束直播 // * 开始直播
*/ // */
public void endLive(Long roomId) { // public void startLive(Long roomId) {
LiveRoom room = liveRoomMapper.selectById(roomId); // LiveRoom room = liveRoomMapper.selectById(roomId);
room.setStatus("ENDED"); // room.setStatus("LIVING");
liveRoomMapper.updateById(room); // liveRoomMapper.updateById(room);
//
// 停止录制 // // 开始录制
stopRecording(room.getStreamKey()); // startRecording(room.getStreamKey());
// }
// 生成回放地址 //
String replayUrl = generateReplayUrl(room.getStreamKey()); // /**
room.setReplayUrl(replayUrl); // * 结束直播
liveRoomMapper.updateById(room); // */
} // public void endLive(Long roomId) {
// LiveRoom room = liveRoomMapper.selectById(roomId);
/** // room.setStatus("ENDED");
* 开始录制 // liveRoomMapper.updateById(room);
*/ //
private void startRecording(String streamKey) { // // 停止录制
SrsClient.RecordConfig config = new SrsClient.RecordConfig(); // stopRecording(room.getStreamKey());
config.setFilePath("/recordings/" + streamKey + ".flv"); //
srsClient.startRecord(streamKey, config); // // 生成回放地址
} // String replayUrl = generateReplayUrl(room.getStreamKey());
// room.setReplayUrl(replayUrl);
/** // liveRoomMapper.updateById(room);
* 停止录制 // }
*/ //
private void stopRecording(String streamKey) { // /**
srsClient.stopRecord(streamKey); // * 开始录制
} // */
// private void startRecording(String streamKey) {
/** // SrsClient.RecordConfig config = new SrsClient.RecordConfig();
* 生成推流密钥 // config.setFilePath("/recordings/" + streamKey + ".flv");
*/ // srsClient.startRecord(streamKey, config);
private String generateStreamKey() { // }
return UUID.randomUUID().toString(); //
} // /**
// * 停止录制
/** // */
* 生成推流地址 // private void stopRecording(String streamKey) {
*/ // srsClient.stopRecord(streamKey);
private String generateRtmpUrl(String streamKey) { // }
return "rtmp://localhost:1935/live/" + streamKey; //
} // /**
// * 生成推流密钥
/** // */
* 生成播放地址 // private String generateStreamKey() {
*/ // return UUID.randomUUID().toString();
private String generateHlsUrl(String streamKey) { // }
return "http://localhost:8088/live/" + streamKey + ".m3u8"; //
} // /**
// * 生成推流地址
/** // */
* 生成回放地址 // private String generateRtmpUrl(String streamKey) {
*/ // return "rtmp://localhost:1935/live/" + streamKey;
private String generateReplayUrl(String streamKey) { // }
return "http://localhost:8080/recordings/" + streamKey + ".flv"; //
} // /**
} // * 生成播放地址
// */
// private String generateHlsUrl(String streamKey) {
// return "http://localhost:8088/live/" + streamKey + ".m3u8";
// }
//
// /**
// * 生成回放地址
// */
// private String generateReplayUrl(String streamKey) {
// return "http://localhost:8080/recordings/" + streamKey + ".flv";
// }
//}

View File

@ -2,11 +2,10 @@ package com.guwan.backend.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.guwan.backend.dto.video.VideoDTO; import com.guwan.backend.dto.video.VideoDTO;
import org.springframework.web.multipart.MultipartFile;
public interface VideoService { public interface VideoService {
// 上传视频 // 上传视频
VideoDTO uploadVideo(MultipartFile file, String title, String description, String tags); VideoDTO uploadVideo(String fileUrl, String title, String description, String tags);
// 更新视频信息 // 更新视频信息
VideoDTO updateVideo(VideoDTO videoDTO); VideoDTO updateVideo(VideoDTO videoDTO);

View File

@ -18,7 +18,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -36,7 +35,7 @@ public class VideoServiceImpl implements VideoService {
@Override @Override
@Transactional @Transactional
@OperationLog(description = "上传视频", operationType = "上传") @OperationLog(description = "上传视频", operationType = "上传")
public VideoDTO uploadVideo(MultipartFile file, String title, String description, String tags) { public VideoDTO uploadVideo(String fileUrl, String title, String description, String tags) {
// 获取当前用户 // 获取当前用户
Long userId = securityUtil.getCurrentUserId(); Long userId = securityUtil.getCurrentUserId();
if (userId == null) { if (userId == null) {
@ -45,15 +44,15 @@ public class VideoServiceImpl implements VideoService {
try { try {
// 上传视频文件到MinIO // 上传视频文件到MinIO
String fileName = minioUtil.uploadFile("videos", file);
String url = minioUtil.getUrl(minioUtil.getFileUrl("videos", fileName)); String url = fileUrl;
// 创建视频记录 // 创建视频记录
Video video = new Video(); Video video = new Video();
video.setTitle(title); video.setTitle(title);
video.setDescription(description); video.setDescription(description);
video.setUrl(url); video.setUrl(url);
video.setSize(file.getSize()); // video.setSize(file.getSize());
video.setUserId(userId); video.setUserId(userId);
video.setStatus("PUBLISHED"); video.setStatus("PUBLISHED");
video.setTags(tags); video.setTags(tags);

View File

@ -172,6 +172,22 @@ public class MinioUtil {
return UUID.randomUUID() + "." + extension; return UUID.randomUUID() + "." + extension;
} }
public long getFileSize(String bucketName, String objectName) {
try {
StatObjectResponse objectInfo = minioClient.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
return objectInfo.size();
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// 初始化时创建视频桶 // 初始化时创建视频桶
@PostConstruct @PostConstruct
public void init() { public void init() {

View File

@ -1,82 +1,82 @@
package com.guwan.backend.websocket; //package com.guwan.backend.websocket;
//
import com.alibaba.fastjson.JSON; //import com.alibaba.fastjson.JSON;
import com.guwan.backend.entity.LiveMessage; //import com.guwan.backend.entity.LiveMessage;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus; //import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage; //import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; //import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler; //import org.springframework.web.socket.handler.TextWebSocketHandler;
//
import java.io.IOException; //import java.io.IOException;
import java.util.Map; //import java.util.Map;
import java.util.Set; //import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; //import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashSet; //import java.util.concurrent.ConcurrentHashSet;
//
@Slf4j //@Slf4j
@Component //@Component
public class LiveWebSocketHandler extends TextWebSocketHandler { //public class LiveWebSocketHandler extends TextWebSocketHandler {
//
private static final Map<String, Set<WebSocketSession>> roomSessions = new ConcurrentHashMap<>(); // private static final Map<String, Set<WebSocketSession>> roomSessions = new ConcurrentHashMap<>();
private static final Map<String, WebSocketSession> userSessions = new ConcurrentHashMap<>(); // private static final Map<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();
//
@Override // @Override
public void afterConnectionEstablished(WebSocketSession session) { // public void afterConnectionEstablished(WebSocketSession session) {
String roomId = getRoomId(session); // String roomId = getRoomId(session);
String userId = getUserId(session); // String userId = getUserId(session);
//
// 加入房间 // // 加入房间
roomSessions.computeIfAbsent(roomId, k -> new ConcurrentHashSet<>()).add(session); // roomSessions.computeIfAbsent(roomId, k -> new ConcurrentHashSet<>()).add(session);
userSessions.put(userId, session); // userSessions.put(userId, session);
//
// 广播进入消息 // // 广播进入消息
broadcastMessage(roomId, createEnterMessage(userId)); // broadcastMessage(roomId, createEnterMessage(userId));
} // }
//
@Override // @Override
public void handleTextMessage(WebSocketSession session, TextMessage message) { // public void handleTextMessage(WebSocketSession session, TextMessage message) {
String roomId = getRoomId(session); // String roomId = getRoomId(session);
LiveMessage liveMessage = JSON.parseObject(message.getPayload(), LiveMessage.class); // LiveMessage liveMessage = JSON.parseObject(message.getPayload(), LiveMessage.class);
//
// 处理不同类型的消息 // // 处理不同类型的消息
switch (liveMessage.getType()) { // switch (liveMessage.getType()) {
case "CHAT": // case "CHAT":
broadcastMessage(roomId, message); // broadcastMessage(roomId, message);
break; // break;
case "GIFT": // case "GIFT":
handleGiftMessage(roomId, liveMessage); // handleGiftMessage(roomId, liveMessage);
break; // break;
case "LIKE": // case "LIKE":
handleLikeMessage(roomId, liveMessage); // handleLikeMessage(roomId, liveMessage);
break; // break;
} // }
} // }
//
@Override // @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { // public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
String roomId = getRoomId(session); // String roomId = getRoomId(session);
String userId = getUserId(session); // String userId = getUserId(session);
//
// 离开房间 // // 离开房间
roomSessions.get(roomId).remove(session); // roomSessions.get(roomId).remove(session);
userSessions.remove(userId); // userSessions.remove(userId);
//
// 广播离开消息 // // 广播离开消息
broadcastMessage(roomId, createLeaveMessage(userId)); // broadcastMessage(roomId, createLeaveMessage(userId));
} // }
//
private void broadcastMessage(String roomId, TextMessage message) { // private void broadcastMessage(String roomId, TextMessage message) {
Set<WebSocketSession> sessions = roomSessions.get(roomId); // Set<WebSocketSession> sessions = roomSessions.get(roomId);
if (sessions != null) { // if (sessions != null) {
sessions.forEach(session -> { // sessions.forEach(session -> {
try { // try {
session.sendMessage(message); // session.sendMessage(message);
} catch (IOException e) { // } catch (IOException e) {
log.error("发送消息失败", e); // log.error("发送消息失败", e);
} // }
}); // });
} // }
} // }
} //}

View File

@ -71,4 +71,11 @@ class MinioUtilTest {
// 删除图片 // 删除图片
// minioUtil.deleteFile(minioConfig.getBucket().getImages(), fileName); // minioUtil.deleteFile(minioConfig.getBucket().getImages(), fileName);
} }
@Test
void testSize() {
System.out.println(minioUtil.getFileSize("images", "7c9360ba-0cf7-41db-9e11-6c02379e1170.jpg"));
}
} }