Signaling server, WS, login, room creation
This commit is contained in:
@@ -11,26 +11,22 @@
|
||||
<groupId>gltronic</groupId>
|
||||
<artifactId>oozik</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>demo</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<name>oozik</name>
|
||||
<description>oozik signaling server</description>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
@@ -48,6 +44,12 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20200518</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package gltronic.oozik;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
17
server/src/main/java/gltronic/oozik/OozikApplication.java
Normal file
17
server/src/main/java/gltronic/oozik/OozikApplication.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package gltronic.oozik;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = "gltronic.oozik")
|
||||
@PropertySource("classpath:application.properties")
|
||||
public class OozikApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OozikApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package gltronic.oozik.business;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.json.JSONObject;
|
||||
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 createRoom(WebSocketSession session) throws InterruptedException, IOException;
|
||||
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException;
|
||||
public void followRTC(WebSocketSession session, JSONObject jsonObject) throws InterruptedException, IOException;
|
||||
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException;
|
||||
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException;
|
||||
}
|
||||
110
server/src/main/java/gltronic/oozik/business/RoomManager.java
Normal file
110
server/src/main/java/gltronic/oozik/business/RoomManager.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package gltronic.oozik.business;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import gltronic.oozik.model.BiMap;
|
||||
|
||||
@Service
|
||||
public class RoomManager implements IRoomManager{
|
||||
BiMap<String, WebSocketSession> users = new BiMap<String, WebSocketSession>();
|
||||
BiMap<String, String> rooms = new BiMap<String, String>();
|
||||
|
||||
public void login(WebSocketSession session, String name) throws InterruptedException, IOException {
|
||||
if (name == null) {
|
||||
sendMessage(session, "error", "bad command command");
|
||||
return;
|
||||
}
|
||||
if (users.containsKey(name)) {
|
||||
sendMessage(session, "login", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
users.put(name, session);
|
||||
sendMessage(session, "login", "true");
|
||||
sendServerInfos(session);
|
||||
|
||||
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 createRoom(WebSocketSession session) throws InterruptedException, IOException {
|
||||
if (!users.containsValue(session)) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
String userName = users.getKey(session);
|
||||
if (rooms.containsKey(userName)) {
|
||||
sendMessage(session, "error", "no multiple room");
|
||||
return;
|
||||
}
|
||||
|
||||
Random random = new Random();
|
||||
String roomName = Integer.toString(random.nextInt(9999));
|
||||
|
||||
while (roomName.length() < 4) roomName += 0 + roomName;
|
||||
|
||||
rooms.put(roomName, userName);
|
||||
sendMessage(session, "createRoom", roomName);
|
||||
|
||||
System.err.println("[ROOM] Created room "+roomName+" by "+userName);
|
||||
}
|
||||
|
||||
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException {
|
||||
if (roomName == null) {
|
||||
sendMessage(session, "error", "bad command command");
|
||||
return;
|
||||
}
|
||||
if (!users.containsValue(session)) {
|
||||
sendMessage(session, "error", "need login");
|
||||
return;
|
||||
}
|
||||
if (!rooms.containsKey(roomName)) {
|
||||
sendMessage(session, "error", "no room");
|
||||
return;
|
||||
}
|
||||
|
||||
String roomAdmin = rooms.getKey(roomName);
|
||||
sendMessage(session, "coonectRoom", roomAdmin);
|
||||
}
|
||||
|
||||
public void followRTC(WebSocketSession session, JSONObject jsonObject) throws InterruptedException, IOException {
|
||||
String target = (String) jsonObject.get("target");
|
||||
String type = (String) jsonObject.get("type");
|
||||
String data = (String) jsonObject.get("data");
|
||||
|
||||
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");
|
||||
sendMessage(targetSession, type, data);
|
||||
}
|
||||
|
||||
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException {
|
||||
session.sendMessage(new TextMessage("{\"type\":\""+type+"\",\"message\":\""+message+"\"}"));
|
||||
}
|
||||
|
||||
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException {
|
||||
session.sendMessage(new TextMessage("{\"type\":\"serverInfos\",\"userCount\":\""+users.size()+"\",\"roomCount\":\""+rooms.size()+"\"}"));
|
||||
}
|
||||
|
||||
}
|
||||
46
server/src/main/java/gltronic/oozik/model/BiMap.java
Normal file
46
server/src/main/java/gltronic/oozik/model/BiMap.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package gltronic.oozik.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BiMap<K, V> {
|
||||
HashMap<K,V> map = new HashMap<K, V>();
|
||||
HashMap<V,K> inversedMap = new HashMap<V, K>();
|
||||
|
||||
public void put(K k, V v) {
|
||||
map.put(k, v);
|
||||
inversedMap.put(v, k);
|
||||
}
|
||||
|
||||
public V get(K k) {
|
||||
return map.get(k);
|
||||
}
|
||||
|
||||
public K getKey(V v) {
|
||||
return inversedMap.get(v);
|
||||
}
|
||||
|
||||
public boolean containsKey(K k) {
|
||||
return map.containsKey(k);
|
||||
}
|
||||
|
||||
public boolean containsValue(V v) {
|
||||
return map.containsValue(v);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public void removeKey(K k) {
|
||||
V v = map.get(k);
|
||||
map.remove(k);
|
||||
inversedMap.remove(v);
|
||||
}
|
||||
|
||||
public void removeValue(V v) {
|
||||
K k = inversedMap.get(v);
|
||||
inversedMap.remove(v);
|
||||
map.remove(k);
|
||||
}
|
||||
|
||||
}
|
||||
60
server/src/main/java/gltronic/oozik/web/SocketHandler.java
Normal file
60
server/src/main/java/gltronic/oozik/web/SocketHandler.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package gltronic.oozik.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
|
||||
import gltronic.oozik.business.IRoomManager;
|
||||
|
||||
@Component
|
||||
public class SocketHandler extends TextWebSocketHandler {
|
||||
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Autowired
|
||||
IRoomManager roomManager;
|
||||
|
||||
@Override
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||
System.err.println("SOCKET MESSAGE :" + message.getPayload());
|
||||
|
||||
String payload = message.getPayload();
|
||||
JSONObject jsonObject = new JSONObject(payload);
|
||||
|
||||
String type = (String) jsonObject.get("type");
|
||||
switch (type) {
|
||||
case "serverInfos":
|
||||
roomManager.sendServerInfos(session);
|
||||
break;
|
||||
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);
|
||||
case "offer":
|
||||
case "answer":
|
||||
case "candidate":
|
||||
roomManager.followRTC(session, jsonObject);
|
||||
default:
|
||||
roomManager.sendMessage(session, "error", "unknow command");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
System.err.println("[WS] new connection");
|
||||
sessions.add(session);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package gltronic.oozik.web;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfiguration implements WebSocketConfigurer {
|
||||
|
||||
@Autowired
|
||||
private SocketHandler socketHandler;
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(socketHandler, "/socket").setAllowedOrigins("*");
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
|
||||
server.port=8181
|
||||
|
||||
Reference in New Issue
Block a user