Fully converted to full socket

This commit is contained in:
Thomas
2020-08-12 14:57:09 +02:00
parent 167dcc354d
commit c1b3280fff
14 changed files with 340 additions and 125 deletions

View File

@@ -29,15 +29,16 @@ export default {
name: 'Admin', name: 'Admin',
computed: { computed: {
usersList () { usersList () {
return this.$store.state.rtc.peers // return this.$store.state.rtc.peers
return []
} }
}, },
methods: { methods: {
broadcastStatus () { broadcastStatus () {
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' }) // this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
}, },
kickUser (target) { kickUser (target) {
this.$store.dispatch('rtc/kick', target) // this.$store.dispatch('rtc/kick', target)
} }
} }
} }

View File

@@ -29,6 +29,8 @@
</template> </template>
<script> <script>
import { send } from '@/store/signalPlugin'
export default { export default {
name: 'Player', name: 'Player',
computed: { computed: {
@@ -118,7 +120,7 @@ export default {
if (this.roomStatus.player.playing) this.player.pauseVideo() if (this.roomStatus.player.playing) this.player.pauseVideo()
else this.player.playVideo() else this.player.playVideo()
} else if (this.roomSettings.userControl) { } else if (this.roomSettings.userControl) {
this.$store.dispatch('rtc/broadcast', { message: { type: 'play' }, type: 'userCommand' }) send({ message: { type: 'play' }, type: 'roomUserCommand' })
} }
}, },
async mute () { async mute () {
@@ -130,11 +132,11 @@ export default {
}, },
skip () { skip () {
if (this.isAdmin) this.$store.commit('room/CURRENT_END') if (this.isAdmin) this.$store.commit('room/CURRENT_END')
else if (this.roomSettings.userControl) this.$store.dispatch('rtc/broadcast', { message: { type: 'skip' }, type: 'userCommand' }) else if (this.roomSettings.userControl) send({ message: { type: 'skip' }, type: 'roomUserCommand' })
}, },
seek (time) { seek (time) {
if (this.isAdmin) this.player.seekTo(time, true) if (this.isAdmin) this.player.seekTo(time, true)
else if (this.roomSettings.userControl) this.$store.dispatch('rtc/broadcast', { message: { type: 'seek', argument: time }, type: 'userCommand' }) else if (this.roomSettings.userControl) send({ message: { type: 'seek', argument: time }, type: 'roomUserCommand' })
}, },
async updateTimeCode () { async updateTimeCode () {
if (this.localSettings.playLink) this.$store.dispatch('room/setTimeCode', await this.player.getCurrentTime()) if (this.localSettings.playLink) this.$store.dispatch('room/setTimeCode', await this.player.getCurrentTime())

View File

@@ -31,6 +31,8 @@
</template> </template>
<script> <script>
import { send } from '@/store/signalPlugin'
export default { export default {
name: 'Playlist', name: 'Playlist',
computed: { computed: {
@@ -70,23 +72,24 @@ export default {
}, },
vote (title, link, linkID, isPositive) { vote (title, link, linkID, isPositive) {
if (this.isAdmin) { if (this.isAdmin) {
this.$store.dispatch('room/vote', { title: title, link: link, linkID: linkID, isPositive: isPositive, voterName: this.$store.state.rtc.name }) this.$store.dispatch('room/vote', { title: title, link: link, linkID: linkID, isPositive: isPositive, voterName: this.$store.state.app.name })
} else { } else {
this.sendVote(link, linkID, isPositive) this.sendVote(title, link, linkID, isPositive)
} }
}, },
sendVote (link, linkID, isPositive) { sendVote (title, link, linkID, isPositive) {
const message = { const message = {
type: 'vote', type: 'vote',
title: title,
link: link, link: link,
linkID: linkID, linkID: linkID,
isPositive: isPositive, isPositive: isPositive,
voterName: this.$store.state.rtc.name voterName: this.$store.state.app.name
} }
this.$store.dispatch('rtc/broadcast', { message: message, type: 'vote' }) send({ message: message, type: 'roomVote' })
}, },
hasVoted (play) { hasVoted (play) {
return play.voters.includes(this.$store.state.rtc.name) return play.voters.includes(this.$store.state.app.name)
}, },
removePlay (linkID) { removePlay (linkID) {
this.$store.dispatch('room/removePlay', linkID) this.$store.dispatch('room/removePlay', linkID)

View File

@@ -1,6 +1,7 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { register } from 'register-service-worker' import { register } from 'register-service-worker'
import { ToastProgrammatic as Toast } from 'buefy'
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, { register(`${process.env.BASE_URL}service-worker.js`, {
@@ -18,13 +19,16 @@ if (process.env.NODE_ENV === 'production') {
}, },
updatefound () { updatefound () {
console.log('New content is downloading.') console.log('New content is downloading.')
Toast.open('Update found, downloading...')
}, },
updated () { updated () {
console.log('New content is available; please refresh.') console.log('New content is available; please refresh.')
window.location.reload(true) window.location.reload(true)
Toast.open('App updated !')
}, },
offline () { offline () {
console.log('No internet connection found. App is running in offline mode.') console.log('No internet connection found. App is running in offline mode.')
Toast.open('No internet connection !')
}, },
error (error) { error (error) {
console.error('Error during service worker registration:', error) console.error('Error during service worker registration:', error)

View File

@@ -4,6 +4,7 @@ import router from '@/router/index'
const state = { const state = {
signalServerConnected: false, signalServerConnected: false,
loginSuccess: null, loginSuccess: null,
name: '',
error: null, error: null,
serverStatus: {} serverStatus: {}
} }
@@ -33,17 +34,15 @@ const actions = {
serverStatus ({ commit }, serverStatus) { serverStatus ({ commit }, serverStatus) {
commit('SET_SERVERSTATUS', serverStatus) commit('SET_SERVERSTATUS', serverStatus)
}, },
createRoom ({ commit, dispatch }, code) {
commit('CREATE_ROOM')
dispatch('room/setRoomCode', code, { root: true })
dispatch('room/setAdmin', null, { root: true })
},
connectRoom ({ commit, dispatch }, name) { connectRoom ({ commit, dispatch }, name) {
commit('CONNECT_ROOM') commit('CONNECT_ROOM')
dispatch('rtc/makeOffer', name, { root: true }) // dispatch('rtc/makeOffer', name, { root: true })
}, },
error ({ commit }, error) { error ({ commit }, error) {
commit('ERROR', error) commit('ERROR', error)
},
setName ({ commit }, name) {
commit('SET_NAME', name)
} }
} }
@@ -67,15 +66,15 @@ const mutations = {
SET_SERVERSTATUS (state, serverStatus) { SET_SERVERSTATUS (state, serverStatus) {
state.serverStatus = serverStatus state.serverStatus = serverStatus
}, },
CREATE_ROOM (state) {
router.push({ name: 'Room' })
},
CONNECT_ROOM (state) { CONNECT_ROOM (state) {
router.push({ name: 'Room' }) router.push({ name: 'Room' })
}, },
ERROR (state, error) { ERROR (state, error) {
state.error = error state.error = error
Dialog.alert(error) Dialog.alert(error)
},
SET_NAME (state, name) {
state.name = name
} }
} }

View File

@@ -1,7 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import signal from './signalPlugin' import signal from './signalPlugin'
import rtc from './rtcModule'
import room from './roomModule' import room from './roomModule'
import app from './appModule' import app from './appModule'
@@ -9,7 +8,6 @@ Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
modules: { modules: {
rtc,
app, app,
room room
}, },

View File

@@ -1,3 +1,6 @@
import { send } from './signalPlugin'
import router from '@/router/index'
const state = { const state = {
admin: false, admin: false,
roomStatus: { roomStatus: {
@@ -32,6 +35,13 @@ const getters = {
} }
const actions = { const actions = {
createRoom ({ commit }, roomCode) {
commit('SET_ROOMCODE', roomCode)
commit('SET_ADMIN')
send({ message: state.roomSettings, type: 'roomSettings' })
send({ message: state.roomStatus, type: 'roomStatus' })
router.push({ name: 'Room' })
},
setRoomCode ({ commit }, roomCode) { setRoomCode ({ commit }, roomCode) {
commit('SET_ROOMCODE', roomCode) commit('SET_ROOMCODE', roomCode)
}, },
@@ -44,9 +54,9 @@ const actions = {
setUserCommand ({ commit }, command) { setUserCommand ({ commit }, command) {
commit('SET_USERCOMMAND', command) commit('SET_USERCOMMAND', command)
}, },
setRoomSettings ({ commit, dispatch, state }, roomSettings) { setRoomSettings ({ commit, state }, roomSettings) {
commit('SET_ROOMSETTINGS', roomSettings) commit('SET_ROOMSETTINGS', roomSettings)
if (state.admin) dispatch('rtc/broadcast', { message: state.roomSettings, type: 'settings' }, { root: true }) if (state.admin) send({ message: state.roomSettings, type: 'roomSettings' })
}, },
setLocalSettings ({ commit }, localSettings) { setLocalSettings ({ commit }, localSettings) {
commit('SET_LOCALSETTINGS', localSettings) commit('SET_LOCALSETTINGS', localSettings)
@@ -57,7 +67,7 @@ const actions = {
setTimeCode ({ commit }, timeCode) { setTimeCode ({ commit }, timeCode) {
commit('SET_TIMECODE', timeCode) commit('SET_TIMECODE', timeCode)
}, },
vote ({ commit, dispatch, state }, { title, link, linkID, isPositive, voterName }) { vote ({ commit, state }, { title, link, linkID, isPositive, voterName }) {
console.log('vote on ' + link + ' | ' + linkID + ' (' + isPositive + ') by ' + voterName) console.log('vote on ' + link + ' | ' + linkID + ' (' + isPositive + ') by ' + voterName)
if (isPositive) { if (isPositive) {
commit('ADD_VOTE', { commit('ADD_VOTE', {
@@ -72,13 +82,13 @@ const actions = {
voterName: voterName voterName: voterName
}) })
} }
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true }) send({ message: state.roomStatus, type: 'roomStatus' })
}, },
removePlay ({ commit, dispatch, state }, linkID) { removePlay ({ commit, state }, linkID) {
commit('REMOVE_PLAY', linkID) commit('REMOVE_PLAY', linkID)
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true }) send({ message: state.roomStatus, type: 'roomStatus' })
}, },
setCurrent ({ commit, dispatch }, { playerStatus, timeCode, timeLength, title }) { setCurrent ({ commit }, { playerStatus, timeCode, timeLength, title }) {
switch (playerStatus) { switch (playerStatus) {
case 0: case 0:
commit('CURRENT_END') commit('CURRENT_END')
@@ -94,10 +104,10 @@ const actions = {
default: default:
return return
} }
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true }) send({ message: state.roomStatus, type: 'roomStatus' })
}, },
leave ({ commit, dispatch }) { leave ({ commit }) {
dispatch('rtc/leave', null, { root: true }) send({ type: 'roomLeave' })
commit('SET_ROOMSTATUS', { commit('SET_ROOMSTATUS', {
roomName: '', roomName: '',
roomCode: '', roomCode: '',

View File

@@ -2,7 +2,7 @@ const connection = new WebSocket('ws://localhost:8181/socket')
// const connection = new WebSocket('wss://echo.websocket.org') // const connection = new WebSocket('wss://echo.websocket.org')
// const connection = new WebSocket('wss://voozik.gltronic.ovh/socket') // const connection = new WebSocket('wss://voozik.gltronic.ovh/socket')
// setTimeout(send({ type: 'alive' }), 5000) setTimeout(send({ type: 'alive' }), 5000)
export default function createSignalPlugin () { export default function createSignalPlugin () {
return store => { return store => {
@@ -22,20 +22,6 @@ export default function createSignalPlugin () {
var data = JSON.parse(message.data) var data = JSON.parse(message.data)
switch (data.type) { switch (data.type) {
case 'offer':
console.log('offer from ' + data.name)
store.dispatch('rtc/offer', { offer: data.data, senderName: data.name })
break
case 'answer':
console.log('answer from ' + data.name)
store.dispatch('rtc/answer', { answer: data.data, senderName: data.name })
break
case 'candidate':
store.dispatch('rtc/candidate', { candidate: data.data, senderName: data.name })
break
case 'leave': case 'leave':
store.dispatch('rtc/leave') store.dispatch('rtc/leave')
break break
@@ -48,11 +34,11 @@ export default function createSignalPlugin () {
store.dispatch('app/serverStatus', data) store.dispatch('app/serverStatus', data)
break break
case 'createRoom': case 'roomCreate':
store.dispatch('app/createRoom', data.message) store.dispatch('room/createRoom', data.message)
break break
case 'connectRoom': case 'roomConnect':
store.dispatch('app/connectRoom', data.message) store.dispatch('app/connectRoom', data.message)
break break
@@ -60,6 +46,22 @@ export default function createSignalPlugin () {
store.dispatch('app/error', data.message) store.dispatch('app/error', data.message)
break break
case 'roomStatus':
if (!store.state.room.admin) store.dispatch('room/setRoomStatus', data.message)
break
case 'roomSettings':
if (!store.state.room.admin) store.dispatch('room/setRoomSettings', data.message)
break
case 'roomVote':
store.dispatch('room/vote', { link: data.message.link, linkID: data.message.linkID, isPositive: data.message.isPositive, voterName: data.message.voterName })
break
case 'roomUserCommand':
if (store.state.room.roomSettings.userControl) store.dispatch('room/setUserCommand', data.message)
break
default: default:
break break
} }

View File

@@ -17,6 +17,8 @@
<b-button type="is-primary" size="is-large" @click="makeRoomPrompt">Make a room</b-button> <b-button type="is-primary" size="is-large" @click="makeRoomPrompt">Make a room</b-button>
<hr> <hr>
<b-button @click="changeName">Change name</b-button> <b-button @click="changeName">Change name</b-button>
<hr>
<p>V2.0</p>
<b-modal :active.sync="isQRModalActive" has-modal-card trap-focus> <b-modal :active.sync="isQRModalActive" has-modal-card trap-focus>
<QRReader v-on:get-code="connectToRoom"/> <QRReader v-on:get-code="connectToRoom"/>
</b-modal> </b-modal>
@@ -54,7 +56,7 @@ export default {
return this.$store.state.app.loginSuccess return this.$store.state.app.loginSuccess
}, },
userName () { userName () {
return this.$store.state.rtc.name return this.$store.state.app.name
} }
}, },
watch: { watch: {
@@ -101,7 +103,7 @@ export default {
type: 'login', type: 'login',
name: name name: name
}) })
this.$store.dispatch('rtc/setName', name) this.$store.dispatch('app/setName', name)
}, },
makeRoomPrompt () { makeRoomPrompt () {
this.$buefy.dialog.prompt({ this.$buefy.dialog.prompt({
@@ -119,8 +121,7 @@ export default {
}, },
makeRoom (name) { makeRoom (name) {
send({ send({
type: 'createRoom', type: 'roomCreate'
name: name
}) })
this.$store.dispatch('room/setRoomName', name) this.$store.dispatch('room/setRoomName', name)
}, },
@@ -140,8 +141,8 @@ export default {
}, },
connectToRoom (code) { connectToRoom (code) {
send({ send({
type: 'connectRoom', type: 'roomConnect',
name: code code: code
}) })
}, },
changeName () { changeName () {

View File

@@ -7,10 +7,17 @@ import org.springframework.web.socket.WebSocketSession;
public interface IRoomManager { public interface IRoomManager {
public void login(WebSocketSession session, String name) throws InterruptedException, IOException; 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 createRoom(WebSocketSession session) throws InterruptedException, IOException;
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException; public void connectRoom(WebSocketSession session, String roomCode) throws InterruptedException, IOException;
public void followRTC(WebSocketSession session, TextMessage message) 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 sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException;
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException; public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException;
} }

View File

@@ -1,6 +1,8 @@
package gltronic.voozik.business; package gltronic.voozik.business;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Optional;
import java.util.Random; import java.util.Random;
import org.json.JSONObject; import org.json.JSONObject;
@@ -8,110 +10,246 @@ import org.springframework.stereotype.Service;
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 gltronic.voozik.model.BiMap; import gltronic.voozik.model.VRoom;
import gltronic.voozik.model.VUser;
@Service @Service
public class RoomManager implements IRoomManager{ public class RoomManager implements IRoomManager {
private volatile BiMap<String, WebSocketSession> users = new BiMap<String, WebSocketSession>(); private volatile ArrayList<VUser> users = new ArrayList<VUser>();
private volatile BiMap<String, String> rooms = new BiMap<String, String>(); private volatile ArrayList<VRoom> rooms = new ArrayList<VRoom>();
public void login(WebSocketSession session, String name) throws InterruptedException, IOException { public void login(WebSocketSession session, String name) throws InterruptedException, IOException {
if (name == null) { if (name == null) {
sendMessage(session, "error", "bad command command"); sendMessage(session, "error", "bad command command");
return; return;
} }
if (users.containsKey(name)) {
if (users.stream().anyMatch(user -> user.getSession().equals(session))) {
sendMessage(session, "login", "false"); sendMessage(session, "login", "false");
return; 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"); sendMessage(session, "login", "true");
sendServerInfos(session); sendServerInfos(session);
System.err.println("[ROOM] Logged "+name); System.err.println("[ROOM] Logged " + name);
} }
public void leave(WebSocketSession session) { public void leave(WebSocketSession session) throws InterruptedException, IOException {
String name = users.getKey(session); Optional<VUser> ouser = users.stream().filter(user -> user.getSession().equals(session)).findFirst();
users.removeValue(session);
if(rooms.containsValue(name)) rooms.removeValue(name);
}
public void createRoom(WebSocketSession session) throws InterruptedException, IOException { if (ouser.isEmpty()) {
if (!users.containsValue(session)) {
sendMessage(session, "error", "need login"); sendMessage(session, "error", "need login");
return; return;
} }
String userName = users.getKey(session);
if (rooms.containsKey(userName)) { VUser user = ouser.get();
sendMessage(session, "error", "no multiple room");
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; return;
} }
Random random = new Random(); 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); room.setAdmin(user);
sendMessage(session, "createRoom", roomName); 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 { public void connectRoom(WebSocketSession session, String roomCode) throws InterruptedException, IOException {
if (roomName == null) { if (roomCode == null) {
sendMessage(session, "error", "bad command command"); sendMessage(session, "error", "bad command command");
return; return;
} }
if (!users.containsValue(session)) { if (!users.stream().anyMatch(user -> user.getSession().equals(session))) {
sendMessage(session, "error", "need login"); sendMessage(session, "error", "need login");
return; 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"); sendMessage(session, "error", "no room");
return; return;
} }
String roomAdmin = rooms.get(roomName); VRoom room = oroom.get();
sendMessage(session, "connectRoom", roomAdmin); VUser user = users.stream().filter(suser -> suser.getSession().equals(session)).findFirst().get();
String userName = users.getKey(session); room.getUsers().add(user);
System.err.println("[ROOM] Connection to room "+roomName+" ("+roomAdmin+") by "+userName); 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(); String payload = message.getPayload();
JSONObject jsonObject = new JSONObject(payload); JSONObject jsonObject = new JSONObject(payload);
String target = (String) jsonObject.get("target");
if (target == null) { user.getRoom().setRoomStatus((JSONObject) jsonObject.get("message"));
sendMessage(session, "error", "no target"); broadcast(user.getRoom(), "roomStatus", user.getRoom().getRoomStatus());
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);
} }
public void followMessage (WebSocketSession session, TextMessage message) throws IOException { @Override
session.sendMessage(message); 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 { 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 { 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);
} }
} }

View 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;
}

View 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;
}

View File

@@ -22,7 +22,8 @@ public class SocketHandler extends TextWebSocketHandler {
IRoomManager roomManager; IRoomManager roomManager;
@Override @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()); System.err.println("[WS] message :" + message.getPayload());
String payload = message.getPayload(); String payload = message.getPayload();
@@ -36,19 +37,27 @@ public class SocketHandler extends TextWebSocketHandler {
case "login": case "login":
roomManager.login(session, (String) jsonObject.get("name")); roomManager.login(session, (String) jsonObject.get("name"));
break; break;
case "createRoom":
roomManager.createRoom(session);
break;
case "connectRoom":
roomManager.connectRoom(session, (String) jsonObject.get("name"));
break;
case "leave": case "leave":
roomManager.leave(session); roomManager.leave(session);
break; break;
case "offer": case "roomCreate":
case "answer": roomManager.createRoom(session);
case "candidate": break;
roomManager.followRTC(session, message); 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; break;
case "search": case "search":
break; break;
@@ -66,9 +75,13 @@ public class SocketHandler extends TextWebSocketHandler {
} }
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){ public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
System.err.println("[WS] connection closed"); System.err.println("[WS] connection closed");
sessions.remove(session); sessions.remove(session);
roomManager.leave(session); try {
roomManager.leave(session);
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
} }
} }