|
@@ -1,97 +1,165 @@
|
|
|
package com.ym.mec.web.handler;
|
|
|
|
|
|
-import com.corundumstudio.socketio.AckRequest;
|
|
|
import com.corundumstudio.socketio.BroadcastOperations;
|
|
|
import com.corundumstudio.socketio.SocketIOClient;
|
|
|
import com.corundumstudio.socketio.SocketIONamespace;
|
|
|
import com.corundumstudio.socketio.annotation.OnConnect;
|
|
|
import com.corundumstudio.socketio.annotation.OnDisconnect;
|
|
|
import com.corundumstudio.socketio.annotation.OnEvent;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
import com.ym.mec.web.support.anno.NamespaceReference;
|
|
|
import com.ym.mec.web.support.anno.OnNamespace;
|
|
|
-import org.apache.logging.log4j.LogManager;
|
|
|
-import org.apache.logging.log4j.Logger;
|
|
|
+import lombok.Data;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
import java.util.Collection;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* var socket = io.connect('http://ip:prot/namespeace')
|
|
|
*/
|
|
|
-
|
|
|
+@Slf4j
|
|
|
+@Data
|
|
|
@Component
|
|
|
@OnNamespace("/whiteboard")
|
|
|
public class WhiteboardHandler {
|
|
|
- @NamespaceReference
|
|
|
- private SocketIONamespace namespace;
|
|
|
|
|
|
- private Logger logger = LogManager.getLogger(getClass().getName());
|
|
|
+ // 初始化房间
|
|
|
+ private static final String EVENT_INIT_ROOM = "init-room";
|
|
|
+ // 第一次进入房间
|
|
|
+ private static final String EVENT_FIRST_IN_ROOM = "first-in-room";
|
|
|
+ // 加入房间
|
|
|
+ private static final String EVENT_JOIN_ROOM = "join-room";
|
|
|
+ // 新用户加入
|
|
|
+ private static final String EVENT_NEW_USER = "new-user";
|
|
|
+ // 房间用户改变(加入或退出)
|
|
|
+ private static final String EVENT_ROOM_USER_CHANGE = "room-user-change";
|
|
|
+ // 服务端广播事件
|
|
|
+ private static final String EVENT_SERVER_BROADCAST = "server-broadcast";
|
|
|
+ // 服务端异常广播事件
|
|
|
+ private static final String EVENT_SERVER_VOLATILE_BROADCAST = "server-volatile-broadcast";
|
|
|
+ // 客户端广播
|
|
|
+ private static final String EVENT_CLIENT_BROADCAST = "client-broadcast";
|
|
|
|
|
|
+ @NamespaceReference
|
|
|
+ private SocketIONamespace namespace;
|
|
|
|
|
|
/**
|
|
|
* 发送初始化房间事件
|
|
|
+ * @param client SocketIOClient
|
|
|
*/
|
|
|
@OnConnect
|
|
|
public void onConnect(SocketIOClient client) {
|
|
|
+
|
|
|
+ // 房间ID
|
|
|
+ String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
|
|
|
+
|
|
|
+ log.info("onConnect client={}, ns={}, roomId={}", client.getSessionId(), client.getNamespace().getName(), roomId);
|
|
|
//发送初始化房间事件
|
|
|
- client.sendEvent("init-room");
|
|
|
+ client.sendEvent(EVENT_INIT_ROOM);
|
|
|
+
|
|
|
+ client.set("socket-room", roomId);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 添加@OnDisconnect事件,客户端断开连接时调用
|
|
|
+ * @param client SocketIOClient
|
|
|
*/
|
|
|
@OnDisconnect
|
|
|
public void onDisconnect(SocketIOClient client) {
|
|
|
+
|
|
|
+ // 房间ID
|
|
|
+ String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
|
|
|
+
|
|
|
+ log.info("onDisconnect client={}, ns={}, roomId={}", client.getSessionId(), client.getNamespace().getName(), roomId);
|
|
|
client.disconnect();
|
|
|
+
|
|
|
+ // 删除数据
|
|
|
+ client.del("socket-room");
|
|
|
+ // 通知用户参与所有房间,用户变化信息
|
|
|
+ if (StringUtils.isNotEmpty(roomId)) {
|
|
|
+
|
|
|
+ BroadcastOperations roomOperations = namespace.getRoomOperations(roomId);
|
|
|
+
|
|
|
+ List<String> collect = roomOperations.getClients().stream()
|
|
|
+ .map(x -> x.getSessionId().toString()).distinct().collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(collect)) {
|
|
|
+ roomOperations.sendEvent(EVENT_ROOM_USER_CHANGE, collect);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 加入房间事件
|
|
|
- * @param client
|
|
|
- * @param data
|
|
|
- * @param ackRequest
|
|
|
+ * @param client SocketIOClient
|
|
|
+ * @param roomId 房间ID
|
|
|
*/
|
|
|
- @OnEvent(value = "join-room")
|
|
|
- public void joinRoom(SocketIOClient client, Object data, AckRequest ackRequest) {
|
|
|
- BroadcastOperations roomOperations = namespace.getRoomOperations("whiteboard");
|
|
|
+ @OnEvent(value = EVENT_JOIN_ROOM)
|
|
|
+ public void joinRoom(SocketIOClient client, String roomId) {
|
|
|
+ log.info("joinRoom roomId={}", roomId);
|
|
|
+
|
|
|
+ // 加入房间
|
|
|
+ client.joinRoom(roomId);
|
|
|
+
|
|
|
+ BroadcastOperations roomOperations = namespace.getRoomOperations(roomId);
|
|
|
Collection<SocketIOClient> clients = roomOperations.getClients();
|
|
|
- client.joinRoom("whiteboard");
|
|
|
+
|
|
|
+ log.debug("joinRoom clients={}", clients.size());
|
|
|
if (clients.size() > 1) {
|
|
|
- for (SocketIOClient socketIOClient : clients) {
|
|
|
- roomOperations.sendEvent("new-user", socketIOClient.getSessionId().toString());
|
|
|
- }
|
|
|
+ roomOperations.sendEvent(EVENT_NEW_USER, client.getSessionId().toString());
|
|
|
} else {
|
|
|
//发送
|
|
|
- client.sendEvent("first-in-room");
|
|
|
+ client.sendEvent(EVENT_FIRST_IN_ROOM);
|
|
|
}
|
|
|
+
|
|
|
+ List<String> collect = Optional.of(clients).orElse(Lists.newArrayList()).stream()
|
|
|
+ .map(x -> x.getSessionId().toString()).distinct().collect(Collectors.toList());
|
|
|
//发送
|
|
|
- roomOperations.sendEvent("room-user-change", clients);
|
|
|
+ if (!CollectionUtils.isEmpty(collect)) {
|
|
|
+
|
|
|
+ roomOperations.sendEvent(EVENT_ROOM_USER_CHANGE, collect);
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 转发 server-broadcast =>client-broadcast
|
|
|
- * @param client
|
|
|
- * @param data
|
|
|
- * @param ackRequest
|
|
|
+ * @param roomId 房间ID
|
|
|
+ * @param encryptedData 接收透传数据
|
|
|
+ * @param iv 接收透传数据
|
|
|
*/
|
|
|
- @OnEvent(value = "server-broadcast")
|
|
|
- public void serverBroadcast(SocketIOClient client, Object data, AckRequest ackRequest) {
|
|
|
- BroadcastOperations roomOperations = namespace.getRoomOperations("whiteboard");
|
|
|
- roomOperations.sendEvent("client-broadcast", data);
|
|
|
+ @OnEvent(value = EVENT_SERVER_BROADCAST)
|
|
|
+ public void serverBroadcast(String roomId, Object encryptedData, Object iv) {
|
|
|
+ log.info("serverBroadcast roomId={} data={}, iv={}", roomId, encryptedData, iv);
|
|
|
+
|
|
|
+ BroadcastOperations roomOperations = namespace.getRoomOperations(roomId);
|
|
|
+ // 发送房间广播消息
|
|
|
+ roomOperations.sendEvent(EVENT_CLIENT_BROADCAST, encryptedData, iv);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 转发 server-volatile-broadcast =>client-broadcast
|
|
|
- * @param client
|
|
|
- * @param data
|
|
|
- * @param ackRequest
|
|
|
+ * @param roomId 房间ID
|
|
|
+ * @param encryptedData 接收透传数据
|
|
|
+ * @param iv 接收透传数据
|
|
|
*/
|
|
|
- @OnEvent(value = "server-volatile-broadcast")
|
|
|
- public void serverVolatileBroadcast(SocketIOClient client, Object data, AckRequest ackRequest) {
|
|
|
- BroadcastOperations roomOperations = namespace.getRoomOperations("whiteboard");
|
|
|
- roomOperations.sendEvent("client-broadcast", data);
|
|
|
+ @OnEvent(value = EVENT_SERVER_VOLATILE_BROADCAST)
|
|
|
+ public void serverVolatileBroadcast(String roomId, Object encryptedData, Object iv) {
|
|
|
+ log.info("serverVolatileBroadcast roomId={} data={}, iv={}", roomId, encryptedData, iv);
|
|
|
+
|
|
|
+ BroadcastOperations roomOperations = namespace.getRoomOperations(roomId);
|
|
|
+ // 发送房间广播消息
|
|
|
+ roomOperations.sendEvent(EVENT_CLIENT_BROADCAST, encryptedData, iv);
|
|
|
+
|
|
|
}
|
|
|
}
|