feat: add PlayroomWebSocketHandler
All checks were successful
dev middleware install / deploy (push) Successful in 52s
All checks were successful
dev middleware install / deploy (push) Successful in 52s
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,7 +3,7 @@ target/
|
|||||||
.mvn/wrapper/maven-wrapper.jar
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
!**/src/main/**/target/
|
!**/src/main/**/target/
|
||||||
!**/src/test/**/target/
|
!**/src/test/**/target/
|
||||||
src/main/resources
|
src/main/resources/application.yaml
|
||||||
|
|
||||||
### STS ###
|
### STS ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.springframework.web.socket.WebSocketSession;
|
|||||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||||
import xin.merlin.myplayerbackend.config.RabbitMQConfig;
|
import xin.merlin.myplayerbackend.config.RabbitMQConfig;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@@ -32,7 +34,7 @@ public class PlayroomWebSocketHandler extends TextWebSocketHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||||
Integer userId = (Integer) session.getAttributes().get("id");
|
Integer userId = (Integer) session.getAttributes().get("id");
|
||||||
String payload = "{\"cmd\": \"PING\", \"to\": "+ userId +", \"time\":\""+ LocalDateTime.now() +"\"}";
|
String payload = "{\"cmd\": \"PING\", \"to\": "+ userId +", \"time\":\""+ LocalDateTime.now() +"\", \"playroom\":"+ session.getAttributes().get("r_id")+ "}";
|
||||||
sessionManager.addSession(userId, session);
|
sessionManager.addSession(userId, session);
|
||||||
rabbitTemplate.convertAndSend(RabbitMQConfig.WS_VIDEO_QUEUE,payload);
|
rabbitTemplate.convertAndSend(RabbitMQConfig.WS_VIDEO_QUEUE,payload);
|
||||||
}
|
}
|
||||||
@@ -42,18 +44,53 @@ public class PlayroomWebSocketHandler extends TextWebSocketHandler {
|
|||||||
JSONObject payload = JSONObject.parseObject(message.getPayload());
|
JSONObject payload = JSONObject.parseObject(message.getPayload());
|
||||||
Integer userId = (Integer) session.getAttributes().get("id");
|
Integer userId = (Integer) session.getAttributes().get("id");
|
||||||
if(payload.get("cmd").equals("PONG")) {
|
if(payload.get("cmd").equals("PONG")) {
|
||||||
if(Boolean.TRUE.equals(redis.opsForSet().isMember(IN_ROOM_BASE_KEY + session.getAttributes().get("r_id") + ":", String.valueOf(userId)))){
|
if(Boolean.TRUE.equals(redis.opsForSet().isMember(IN_ROOM_BASE_KEY + session.getAttributes().get("r_id"), String.valueOf(userId)))){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
redis.opsForSet().add(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id")+":", String.valueOf(userId));
|
redis.opsForSet().add(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id"), String.valueOf(userId));
|
||||||
|
}
|
||||||
|
if (payload.get("cmd").equals("VIDEO_SYNC")){
|
||||||
|
String url = payload.getString("url");
|
||||||
|
String timestamp = payload.getString("timestamp");
|
||||||
|
// Integer playroom = (Integer) session.getAttributes().get("r_id");
|
||||||
|
String sending = "{\"cmd\": \"VIDEO_SYNC\", \"from\": "+
|
||||||
|
userId
|
||||||
|
+", \"time\":\""+
|
||||||
|
LocalDateTime.now()
|
||||||
|
+"\", \"url\":\""+
|
||||||
|
url
|
||||||
|
+"\", \"timestamp\":\""+
|
||||||
|
timestamp
|
||||||
|
+"\", \"playroom\":"+
|
||||||
|
session.getAttributes().get("r_id")
|
||||||
|
+"}";
|
||||||
|
Set<String> members = redis.opsForSet().members(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id"));
|
||||||
|
try {
|
||||||
|
for (String member : members) {
|
||||||
|
sessionManager.sendToUser(Integer.valueOf(member),sending);
|
||||||
|
}
|
||||||
|
} catch (IOException | NumberFormatException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(payload.get("cmd").equals("VIDEO_PLAY") || payload.get("cmd").equals("VIDEO_PAUSE")){
|
||||||
|
Set<String> members = redis.opsForSet().members(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id"));
|
||||||
|
try {
|
||||||
|
for (String member : members) {
|
||||||
|
sessionManager.sendToUser(Integer.valueOf(member),message.getPayload());
|
||||||
|
}
|
||||||
|
} catch (IOException | NumberFormatException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||||
Integer userId = (Integer) session.getAttributes().get("id");
|
Integer userId = (Integer) session.getAttributes().get("id");
|
||||||
redis.opsForSet().remove(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id")+":", userId.toString());
|
redis.opsForSet().remove(IN_ROOM_BASE_KEY+session.getAttributes().get("r_id"), userId.toString());
|
||||||
sessionManager.removeSession(userId);
|
sessionManager.removeSession(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import xin.merlin.myplayerbackend.config.RabbitMQConfig;
|
|||||||
import xin.merlin.myplayerbackend.utils.websocket.command.CommandDispatcher;
|
import xin.merlin.myplayerbackend.utils.websocket.command.CommandDispatcher;
|
||||||
import xin.merlin.myplayerbackend.utils.websocket.command.CommandDispatcherVideo;
|
import xin.merlin.myplayerbackend.utils.websocket.command.CommandDispatcherVideo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
|||||||
@@ -8,5 +8,7 @@ public interface BaseCommandHandler {
|
|||||||
void handle(JSONObject msg) throws IOException;
|
void handle(JSONObject msg) throws IOException;
|
||||||
|
|
||||||
void handle(String msg, Integer to) throws IOException;
|
void handle(String msg, Integer to) throws IOException;
|
||||||
|
|
||||||
|
void handle(String msg, Integer from, Integer playroom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import xin.merlin.myplayerbackend.utils.websocket.PlayroomWebSocketSessionManager;
|
import xin.merlin.myplayerbackend.utils.websocket.PlayroomWebSocketSessionManager;
|
||||||
|
import xin.merlin.myplayerbackend.utils.websocket.command.impl.Link;
|
||||||
import xin.merlin.myplayerbackend.utils.websocket.command.impl.Ping;
|
import xin.merlin.myplayerbackend.utils.websocket.command.impl.Ping;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -14,14 +15,18 @@ public class CommandDispatcherVideo {
|
|||||||
|
|
||||||
private final Ping pingCommand;
|
private final Ping pingCommand;
|
||||||
|
|
||||||
|
private final Link linkCommand;
|
||||||
|
|
||||||
|
|
||||||
public void dispatch(JSONObject msg) throws IOException {
|
public void dispatch(JSONObject msg) throws IOException {
|
||||||
String cmd = msg.getString("cmd");
|
String cmd = msg.getString("cmd");
|
||||||
Integer to = Integer.valueOf(msg.getString("to"));
|
Integer to = Integer.valueOf(msg.getString("to"));
|
||||||
|
Integer playroom = Integer.valueOf(msg.getString("playroom"));
|
||||||
String jsonString = msg.toJSONString();
|
String jsonString = msg.toJSONString();
|
||||||
|
|
||||||
switch (cmd){
|
switch (cmd){
|
||||||
case "PING" -> pingCommand.handle(jsonString,to);
|
case "PING" -> pingCommand.handle(jsonString,to);
|
||||||
|
case "LINK" -> linkCommand.handle(jsonString,to,playroom);
|
||||||
default -> {
|
default -> {
|
||||||
// System.err.println("Unknown command: " + cmd);
|
// System.err.println("Unknown command: " + cmd);
|
||||||
// TODO: 这里应该使用default的一个类统一封装
|
// TODO: 这里应该使用default的一个类统一封装
|
||||||
|
|||||||
@@ -49,4 +49,8 @@ public class GroupMessage implements BaseCommandHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,9 @@ public class Heartbeat implements BaseCommandHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(String msg, Integer to) throws IOException {
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package xin.merlin.myplayerbackend.utils.websocket.command.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import xin.merlin.myplayerbackend.utils.websocket.command.BaseCommandHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class Link implements BaseCommandHandler {
|
||||||
|
|
||||||
|
private final RedisTemplate<String, String> redis;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(JSONObject msg) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,10 @@ TODO: 这里需要处理如果目标用户不在线,如何去完成消息的
|
|||||||
@Override
|
@Override
|
||||||
public void handle(String msg, Integer to) throws IOException {
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,9 @@ public class PersonalNotify implements BaseCommandHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(String msg, Integer to) throws IOException {
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,5 +29,9 @@ public class Ping implements BaseCommandHandler {
|
|||||||
System.out.println(to+":"+msg);
|
System.out.println(to+":"+msg);
|
||||||
playroomWebSocketSessionManager.sendToUser(to, msg);
|
playroomWebSocketSessionManager.sendToUser(to, msg);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ public class SystemNotify implements BaseCommandHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(String msg, Integer to) throws IOException {
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,9 @@ public class Typing implements BaseCommandHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(String msg, Integer to) throws IOException {
|
public void handle(String msg, Integer to) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handle(String msg, Integer from, Integer playroom) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
96
src/main/resources/application_template.yaml
Normal file
96
src/main/resources/application_template.yaml
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
secret:
|
||||||
|
issuer:
|
||||||
|
subject:
|
||||||
|
expire: 604800
|
||||||
|
|
||||||
|
aes:
|
||||||
|
# aes16/32/48位key
|
||||||
|
key:
|
||||||
|
|
||||||
|
resources:
|
||||||
|
public: C://resources/public
|
||||||
|
user:
|
||||||
|
avatar: C://resources/user/avatar
|
||||||
|
group:
|
||||||
|
avatar: C://resources/group/avatar
|
||||||
|
playroom:
|
||||||
|
avatar: C://resources/group/avatar
|
||||||
|
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: myplayer-backend
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 50MB
|
||||||
|
max-request-size: 10MB
|
||||||
|
datasource:
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
url: jdbc:postgresql://localhost:5432/myplayer
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
|
||||||
|
mail:
|
||||||
|
protocol: smtps
|
||||||
|
port: 465
|
||||||
|
default-encoding: utf-8
|
||||||
|
host: smtp.163.com
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
properties:
|
||||||
|
mail:
|
||||||
|
smtp:
|
||||||
|
auth: true
|
||||||
|
ssl:
|
||||||
|
enable: false
|
||||||
|
required: false
|
||||||
|
protocols: TLSv1.2
|
||||||
|
connectiontimeout: 10000
|
||||||
|
timeout: 15000
|
||||||
|
writetimeout: 10000
|
||||||
|
debug: true
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
password: dctf8nUrn3
|
||||||
|
# database: 0
|
||||||
|
timeout: 2000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 8
|
||||||
|
max-idle: 8
|
||||||
|
min-idle: 0
|
||||||
|
rabbitmq:
|
||||||
|
host: localhost
|
||||||
|
port: 5672
|
||||||
|
username: user
|
||||||
|
password: Aqe5U57kvj50k7rG
|
||||||
|
virtual-host: /
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
table-prefix: "" # 可选:表前缀(没有可以留空)
|
||||||
|
id-type: auto # 主键策略
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: false # 禁用驼峰命名自动映射
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印 SQL(调试用)
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
org:
|
||||||
|
springframework:
|
||||||
|
security: DEBUG
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
api-docs:
|
||||||
|
enabled: true
|
||||||
|
path: /v3/api-docs
|
||||||
|
swagger-ui:
|
||||||
|
enabled: true
|
||||||
|
path: /v3/api-docs/swagger-ui.html
|
||||||
Reference in New Issue
Block a user