Fully converted to full socket
This commit is contained in:
@@ -7,10 +7,17 @@ import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
public interface IRoomManager {
|
||||
public void login(WebSocketSession session, String name) throws InterruptedException, IOException;
|
||||
public void leave(WebSocketSession session);
|
||||
public void leave(WebSocketSession session) throws InterruptedException, IOException;
|
||||
|
||||
public void createRoom(WebSocketSession session) throws InterruptedException, IOException;
|
||||
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException;
|
||||
public void followRTC(WebSocketSession session, TextMessage message) throws InterruptedException, IOException;
|
||||
public void connectRoom(WebSocketSession session, String roomCode) throws InterruptedException, IOException;
|
||||
public void leaveRoom(WebSocketSession session) throws InterruptedException, IOException;
|
||||
|
||||
public void setRoomStatus(WebSocketSession session, TextMessage message) throws InterruptedException, IOException;
|
||||
public void setRoomSettings(WebSocketSession session, TextMessage message) throws InterruptedException, IOException;
|
||||
|
||||
public void forwardRoomMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException;
|
||||
|
||||
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException;
|
||||
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package gltronic.voozik.business;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.json.JSONObject;
|
||||
@@ -8,110 +10,246 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import gltronic.voozik.model.BiMap;
|
||||
import gltronic.voozik.model.VRoom;
|
||||
import gltronic.voozik.model.VUser;
|
||||
|
||||
@Service
|
||||
public class RoomManager implements IRoomManager{
|
||||
private volatile BiMap<String, WebSocketSession> users = new BiMap<String, WebSocketSession>();
|
||||
private volatile BiMap<String, String> rooms = new BiMap<String, String>();
|
||||
public class RoomManager implements IRoomManager {
|
||||
private volatile ArrayList<VUser> users = new ArrayList<VUser>();
|
||||
private volatile ArrayList<VRoom> rooms = new ArrayList<VRoom>();
|
||||
|
||||
public void login(WebSocketSession session, String name) throws InterruptedException, IOException {
|
||||
if (name == null) {
|
||||
sendMessage(session, "error", "bad command command");
|
||||
return;
|
||||
}
|
||||
if (users.containsKey(name)) {
|
||||
|
||||
if (users.stream().anyMatch(user -> user.getSession().equals(session))) {
|
||||
sendMessage(session, "login", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
users.put(name, session);
|
||||
if (users.stream().anyMatch(user -> user.getName().equals(name))) {
|
||||
sendMessage(session, "login", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = new VUser();
|
||||
user.setName(name);
|
||||
user.setSession(session);
|
||||
|
||||
users.add(user);
|
||||
|
||||
sendMessage(session, "login", "true");
|
||||
sendServerInfos(session);
|
||||
|
||||
System.err.println("[ROOM] Logged "+name);
|
||||
System.err.println("[ROOM] Logged " + name);
|
||||
}
|
||||
|
||||
public void leave(WebSocketSession session) {
|
||||
String name = users.getKey(session);
|
||||
users.removeValue(session);
|
||||
if(rooms.containsValue(name)) rooms.removeValue(name);
|
||||
}
|
||||
public void leave(WebSocketSession session) throws InterruptedException, IOException {
|
||||
Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
|
||||
|
||||
public void createRoom(WebSocketSession session) throws InterruptedException, IOException {
|
||||
if (!users.containsValue(session)) {
|
||||
if (ouser.isEmpty()) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
String userName = users.getKey(session);
|
||||
if (rooms.containsKey(userName)) {
|
||||
sendMessage(session, "error", "no multiple room");
|
||||
|
||||
VUser user = ouser.get();
|
||||
|
||||
users.remove(user);
|
||||
Optional<VRoom> oroom = rooms.stream().filter(room -> room.getUsers().contains(user)).findFirst();
|
||||
|
||||
if (oroom.isPresent()) {
|
||||
oroom.get().getUsers().remove(user);
|
||||
}
|
||||
}
|
||||
|
||||
public void createRoom(WebSocketSession session) throws InterruptedException, IOException {
|
||||
if (!users.stream().anyMatch(user -> user.getSession().equals(session))) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = users.stream().filter(suser -> suser.getSession().equals(session)).findFirst().get();
|
||||
|
||||
if (user.getRoom() != null) {
|
||||
sendMessage(session, "error", "no already in room");
|
||||
return;
|
||||
}
|
||||
|
||||
Random random = new Random();
|
||||
String roomName = Integer.toString(random.nextInt(9999));
|
||||
String roomCode = Integer.toString(random.nextInt(9999));
|
||||
while (roomCode.length() < 4)
|
||||
roomCode += 0 + roomCode;
|
||||
|
||||
while (roomName.length() < 4) roomName += 0 + roomName;
|
||||
VRoom room = new VRoom();
|
||||
|
||||
rooms.put(roomName, userName);
|
||||
sendMessage(session, "createRoom", roomName);
|
||||
room.setAdmin(user);
|
||||
room.setCode(roomCode);
|
||||
room.setPublic(false);
|
||||
room.setUsers(new ArrayList<VUser>());
|
||||
|
||||
System.err.println("[ROOM] Created room "+roomName+" by "+userName);
|
||||
rooms.add(room);
|
||||
user.setRoom(room);
|
||||
|
||||
sendMessage(session, "roomCreate", roomCode);
|
||||
|
||||
System.err.println("[ROOM] Created room " + roomCode + " by " + user.getName());
|
||||
}
|
||||
|
||||
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException {
|
||||
if (roomName == null) {
|
||||
public void connectRoom(WebSocketSession session, String roomCode) throws InterruptedException, IOException {
|
||||
if (roomCode == null) {
|
||||
sendMessage(session, "error", "bad command command");
|
||||
return;
|
||||
}
|
||||
if (!users.containsValue(session)) {
|
||||
if (!users.stream().anyMatch(user -> user.getSession().equals(session))) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
if (!rooms.containsKey(roomName)) {
|
||||
|
||||
Optional<VRoom> oroom = rooms.stream().filter(room -> room.getCode().equals(roomCode)).findFirst();
|
||||
if (oroom.isEmpty()) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
String roomAdmin = rooms.get(roomName);
|
||||
sendMessage(session, "connectRoom", roomAdmin);
|
||||
VRoom room = oroom.get();
|
||||
VUser user = users.stream().filter(suser -> suser.getSession().equals(session)).findFirst().get();
|
||||
|
||||
String userName = users.getKey(session);
|
||||
System.err.println("[ROOM] Connection to room "+roomName+" ("+roomAdmin+") by "+userName);
|
||||
room.getUsers().add(user);
|
||||
user.setRoom(room);
|
||||
|
||||
sendMessage(session, "roomConnect", "true");
|
||||
forwardMessage(session, "roomStatus", room.getRoomStatus());
|
||||
forwardMessage(session, "roomSettings", room.getRoomSettings());
|
||||
|
||||
System.err
|
||||
.println("[ROOM] Connection to room " + roomCode + " (" + room.getAdmin().getName() + ") by " + user.getName());
|
||||
}
|
||||
|
||||
public void followRTC(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
@Override
|
||||
public void leaveRoom(WebSocketSession session) throws InterruptedException, IOException {
|
||||
Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
|
||||
|
||||
if (ouser.isEmpty()) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = ouser.get();
|
||||
|
||||
if (user.getRoom() == null) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
user.getRoom().getUsers().remove(user);
|
||||
user.setRoom(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRoomStatus(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
|
||||
|
||||
if (ouser.isEmpty()) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = ouser.get();
|
||||
|
||||
if (user.getRoom() == null) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.getRoom().getAdmin().equals(user)) {
|
||||
sendMessage(session, "error", "not admin");
|
||||
return;
|
||||
}
|
||||
|
||||
String payload = message.getPayload();
|
||||
JSONObject jsonObject = new JSONObject(payload);
|
||||
String target = (String) jsonObject.get("target");
|
||||
|
||||
if (target == null) {
|
||||
sendMessage(session, "error", "no target");
|
||||
return;
|
||||
}
|
||||
|
||||
WebSocketSession targetSession = users.get(target);
|
||||
|
||||
if (targetSession == null) {
|
||||
sendMessage(session, "error", "unknow target");
|
||||
return;
|
||||
}
|
||||
|
||||
System.err.println("[ROOM] Foward RTC message");
|
||||
followMessage(targetSession, message);
|
||||
user.getRoom().setRoomStatus((JSONObject) jsonObject.get("message"));
|
||||
broadcast(user.getRoom(), "roomStatus", user.getRoom().getRoomStatus());
|
||||
}
|
||||
|
||||
public void followMessage (WebSocketSession session, TextMessage message) throws IOException {
|
||||
session.sendMessage(message);
|
||||
@Override
|
||||
public void setRoomSettings(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
|
||||
|
||||
if (ouser.isEmpty()) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = ouser.get();
|
||||
|
||||
if (user.getRoom() == null) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.getRoom().getAdmin().equals(user)) {
|
||||
sendMessage(session, "error", "not admin");
|
||||
return;
|
||||
}
|
||||
|
||||
String payload = message.getPayload();
|
||||
JSONObject jsonObject = new JSONObject(payload);
|
||||
|
||||
user.getRoom().setRoomSettings((JSONObject) jsonObject.get("message"));
|
||||
broadcast(user.getRoom(), "roomSettings", user.getRoom().getRoomSettings());
|
||||
}
|
||||
|
||||
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException {
|
||||
session.sendMessage(new TextMessage("{\"type\":\""+type+"\",\"message\":\""+message+"\"}"));
|
||||
session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": \"" + message.toString() + "\" }"));
|
||||
}
|
||||
|
||||
public void forwardMessage(WebSocketSession session, String type, JSONObject message) throws InterruptedException, IOException {
|
||||
session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": " + message.toString() + " }"));
|
||||
}
|
||||
|
||||
public void broadcast(VRoom room, String type, JSONObject message) {
|
||||
room.getUsers().forEach(user -> {
|
||||
try {
|
||||
forwardMessage(user.getSession(), type, message);
|
||||
} catch (InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException {
|
||||
session.sendMessage(new TextMessage("{\"type\":\"serverInfos\",\"userCount\":\""+users.size()+"\",\"roomCount\":\""+rooms.size()+"\"}"));
|
||||
session.sendMessage(new TextMessage(
|
||||
"{\"type\":\"serverInfos\",\"userCount\":\"" + users.size() + "\",\"roomCount\":\"" + rooms.size() + "\"}"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forwardRoomMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
|
||||
|
||||
if (ouser.isEmpty()) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
|
||||
VUser user = ouser.get();
|
||||
|
||||
if (user.getRoom() == null) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
String payload = message.getPayload();
|
||||
JSONObject jsonObject = new JSONObject(payload);
|
||||
String type = (String) jsonObject.get("type");
|
||||
JSONObject data = (JSONObject) jsonObject.get("message");
|
||||
|
||||
if (user.getRoom().getAdmin().equals(user)) broadcast(user.getRoom(), type, data);
|
||||
else forwardMessage(user.getRoom().getAdmin().getSession(), type, data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
21
server/src/main/java/gltronic/voozik/model/VRoom.java
Normal file
21
server/src/main/java/gltronic/voozik/model/VRoom.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package gltronic.voozik.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class VRoom {
|
||||
private String code;
|
||||
private boolean isPublic;
|
||||
private JSONObject roomStatus;
|
||||
private JSONObject roomSettings;
|
||||
private VUser admin;
|
||||
private List<VUser> users;
|
||||
}
|
||||
16
server/src/main/java/gltronic/voozik/model/VUser.java
Normal file
16
server/src/main/java/gltronic/voozik/model/VUser.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package gltronic.voozik.model;
|
||||
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class VUser {
|
||||
private String name;
|
||||
private WebSocketSession session;
|
||||
private VRoom room;
|
||||
}
|
||||
@@ -22,12 +22,13 @@ public class SocketHandler extends TextWebSocketHandler {
|
||||
IRoomManager roomManager;
|
||||
|
||||
@Override
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message)
|
||||
throws InterruptedException, IOException {
|
||||
System.err.println("[WS] message :" + message.getPayload());
|
||||
|
||||
|
||||
String payload = message.getPayload();
|
||||
JSONObject jsonObject = new JSONObject(payload);
|
||||
|
||||
|
||||
String type = (String) jsonObject.get("type");
|
||||
switch (type) {
|
||||
case "serverInfos":
|
||||
@@ -36,19 +37,27 @@ public class SocketHandler extends TextWebSocketHandler {
|
||||
case "login":
|
||||
roomManager.login(session, (String) jsonObject.get("name"));
|
||||
break;
|
||||
case "createRoom":
|
||||
roomManager.createRoom(session);
|
||||
break;
|
||||
case "connectRoom":
|
||||
roomManager.connectRoom(session, (String) jsonObject.get("name"));
|
||||
break;
|
||||
case "leave":
|
||||
roomManager.leave(session);
|
||||
break;
|
||||
case "offer":
|
||||
case "answer":
|
||||
case "candidate":
|
||||
roomManager.followRTC(session, message);
|
||||
case "roomCreate":
|
||||
roomManager.createRoom(session);
|
||||
break;
|
||||
case "roomConnect":
|
||||
roomManager.connectRoom(session, (String) jsonObject.get("code"));
|
||||
break;
|
||||
case "roomLeave":
|
||||
roomManager.leaveRoom(session);
|
||||
break;
|
||||
case "roomStatus":
|
||||
roomManager.setRoomStatus(session, message);
|
||||
break;
|
||||
case "roomSettings":
|
||||
roomManager.setRoomSettings(session, message);
|
||||
break;
|
||||
case "roomVote":
|
||||
case "roomUserCommand":
|
||||
roomManager.forwardRoomMessage(session, message);
|
||||
break;
|
||||
case "search":
|
||||
break;
|
||||
@@ -66,9 +75,13 @@ public class SocketHandler extends TextWebSocketHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
|
||||
System.err.println("[WS] connection closed");
|
||||
sessions.remove(session);
|
||||
roomManager.leave(session);
|
||||
try {
|
||||
roomManager.leave(session);
|
||||
} catch (InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user