Signaling server, WS, login, room creation

This commit is contained in:
Thomas
2020-07-27 21:44:36 +02:00
parent 0ef9ba675b
commit c1787cacba
25 changed files with 1114 additions and 123 deletions

View File

@@ -0,0 +1,75 @@
import { DialogProgrammatic as Dialog } from 'buefy'
import router from '@/router/index'
const state = {
signalServerConnected: false,
loginSuccess: false,
error: null,
serverStatus: {}
}
const getters = {
displayError: state => state.error,
displayUserList: state => state.userList,
displayLoginStatus: state => state.loginSuccess,
displayServerStatus: state => state.signalServerConnected
}
const actions = {
signalConnected ({ commit }) {
commit('SIGNAL_SUCCESS')
},
signalError ({ commit }, error) {
commit('SIGNAL_ERROR', error)
},
login ({ commit }, success) {
if (success) commit('LOGIN_SUCCESS')
else commit('LOGIN_ERROR')
},
serverStatus ({ commit }, serverStatus) {
commit('SET_SERVERSTATUS', serverStatus)
},
createRoom ({ commit, dispatch }, code) {
commit('CREATE_ROOM')
dispatch('room/setRoomCode', code, { root: true })
},
error ({ commit }, error) {
commit('ERROR', error)
}
}
const mutations = {
SIGNAL_SUCCESS (state) {
state.signalServerConnected = true
},
SIGNAL_ERROR (state, error) {
state.signalServerConnected = false
state.error = error
},
LOGIN_SUCCESS (state) {
state.loginSuccess = true
},
LOGIN_ERROR (state) {
state.loginSuccess = false
},
SET_SERVERSTATUS (state, serverStatus) {
state.serverStatus = serverStatus
},
CREATE_ROOM (state) {
state.room = true
state.admin = true
router.push({ name: 'Room' })
},
ERROR (state, error) {
state.error = error
Dialog.alert(error)
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}

View File

@@ -1,15 +1,19 @@
import Vue from 'vue'
import Vuex from 'vuex'
import signal from './signalPlugin'
import rtc from './rtcModule'
import room from './roomModule'
import app from './appModule'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
rtc,
app,
room
},
plugins: [
signal()
]
})

View File

@@ -0,0 +1,46 @@
const state = {
admin: false,
roomStatus: {
roomName: '',
roomCode: '',
current: '',
playlist: []
}
}
const getters = {
displayRoomCode: state => state.roomCode,
displayRoomName: state => state.roomName
}
const actions = {
setRoomCode ({ commit }, roomCode) {
commit('SET_ROOMCODE', roomCode)
},
setRoomName ({ commit }, roomName) {
commit('SET_ROOMNAME', roomName)
},
setRoomStatus ({ commit }, roomStatus) {
commit('SET_ROOMSTATUS', roomStatus)
}
}
const mutations = {
SET_ROOMCODE (state, code) {
state.roomStatus.roomCode = code
},
SET_ROOMNAME (state, name) {
state.roomStatus.roomName = name
},
SET_ROOMSTATUS (state, roomStatus) {
state.roomStatus = roomStatus
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}

View File

@@ -0,0 +1,128 @@
import { send } from './signalPlugin'
const configuration = {
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
}
const state = {
name: null,
connections: new Map()
}
const getters = {
displayName: state => state.name
}
const actions = {
setName ({ commit }, name) {
commit('SET_NAME', name)
},
async offer ({ commit }, offer, name) {
commit('CREATE_PEER_CONNECTION', name)
commit('ANSWER', name, offer)
},
answer ({ commit }, answer, name) {
commit('OFFER', name, answer)
},
candidate ({ commit }, candidate, name) {
commit('ANSWER', name, candidate)
},
leave ({ commit }) {
commit('LEAVE')
},
broadcast ({ commit }, message) {
commit('BROADCAST', message)
}
}
const mutations = {
SET_NAME (state, name) {
state.name = name
},
CREATE_PEER_CONNECTION (state, target) {
console.log('CREATED PEER CONNECTION')
var connection = new RTCPeerConnection(configuration)
state.connections[target] = connection
connection.onicecandidate = function (event) {
if (event.candidate) {
send({
type: 'candidate',
name: name,
target: target,
candidate: event.candidate
})
}
}
connection.onnegotiationneeded = function () { handleNegotiationNeededEvent(target) }
connection.onsignalingstatechange = function () { handleSignalingStateChangeEvent(connection) }
connection.oniceconnectionstatechange = function () { handleICEConnectionStateChangeEvent(connection) }
connection.onicegatheringstatechange = function () { handleICEGatheringStateChangeEvent(connection) }
},
CREATE_DATA_CHANNEL (state) {
},
ANSWER (state, target, offer) {
var connection = state.connections[target]
connection.setRemoteDescription(new RTCSessionDescription(offer))
var answer = connection.createAnswer()
connection.setLocalDescription(answer)
send({
type: 'answer',
name: name,
target: target,
answer: answer
})
},
OFFER (state, target, answer) {
var connection = state.connections[target]
connection.setRemoteDescription(new RTCSessionDescription(answer))
},
CANDIDATE (state, target, candidate) {
var connection = state.connections[target]
connection.addIceCandidate(new RTCIceCandidate(candidate))
},
LEAVE (state) {
state.connections.forEach((connection) => {
connection.close()
connection = null
})
state.connections = new Map()
},
BROADCAST (state, message) {
}
}
function handleICEConnectionStateChangeEvent (connection) {
console.log('ICE CONNECTION CHANGE ' + connection.iceConnectionState)
}
function handleICEGatheringStateChangeEvent (connection) {
console.log('ICE GATHERING CHANGE ' + connection.iceGatheringState)
}
async function handleNegotiationNeededEvent (target) {
console.log('NEGOTIATION NEEDED FROM ' + target)
}
async function handleSignalingStateChangeEvent (connection) {
console.log('STATE CHANGED TO : ' + connection.signalingState)
switch (connection.signalingState) {
case 'closed':
await connection.close()
break
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}

View File

@@ -0,0 +1,64 @@
const connection = new WebSocket('ws://localhost:8181/socket')
// const connection = new WebSocket('wss://echo.websocket.org')
export default function createSignalPlugin () {
return store => {
connection.onopen = function () {
console.log('WS connected')
store.dispatch('app/signalConnected')
}
connection.onerror = function (error) {
console.log('WS error ' + error)
store.dispatch('app/signalError', error)
}
connection.onmessage = function (message) {
console.log('WS message', message.data)
var data = JSON.parse(message.data)
switch (data.type) {
case 'offer':
store.dispatch('rtc/offer', data.offer, data.name)
break
case 'answer':
store.dispatch('rtc/answer', data.answer, data.name)
break
case 'candidate':
store.dispatch('rtc/candidate', data.candidate, data.name)
break
case 'leave':
store.dispatch('rtc/leave')
break
case 'login':
store.dispatch('app/login', data.message)
break
case 'serverInfos':
store.dispatch('app/serverStatus', data)
break
case 'createRoom':
store.dispatch('app/createRoom', data.message)
break
case 'error':
store.dispatch('app/error', data.message)
break
default:
break
}
}
}
}
export function send (message) {
console.log('WS send', message)
connection.send(JSON.stringify(message))
}