working rtc connection

This commit is contained in:
Thomas
2020-07-28 20:31:15 +02:00
parent c1787cacba
commit 927fa2d1a2
11 changed files with 208 additions and 79 deletions

View File

@@ -32,6 +32,11 @@ const actions = {
createRoom ({ commit, dispatch }, code) {
commit('CREATE_ROOM')
dispatch('room/setRoomCode', code, { root: true })
dispatch('room/setAdmin', null, { root: true })
},
connectRoom ({ commit, dispatch }, name) {
commit('CONNECT_ROOM')
dispatch('rtc/makeOffer', name, { root: true })
},
error ({ commit }, error) {
commit('ERROR', error)
@@ -56,8 +61,9 @@ const mutations = {
state.serverStatus = serverStatus
},
CREATE_ROOM (state) {
state.room = true
state.admin = true
router.push({ name: 'Room' })
},
CONNECT_ROOM (state) {
router.push({ name: 'Room' })
},
ERROR (state, error) {

View File

@@ -9,8 +9,6 @@ const state = {
}
const getters = {
displayRoomCode: state => state.roomCode,
displayRoomName: state => state.roomName
}
const actions = {
@@ -22,6 +20,9 @@ const actions = {
},
setRoomStatus ({ commit }, roomStatus) {
commit('SET_ROOMSTATUS', roomStatus)
},
setAdmin ({ commit }) {
commit('SET_ADMIN')
}
}
@@ -34,6 +35,12 @@ const mutations = {
},
SET_ROOMSTATUS (state, roomStatus) {
state.roomStatus = roomStatus
},
SET_ADMIN (state) {
state.admin = true
},
BROADCAST_ROOMSTATUS (state) {
}
}

View File

@@ -1,4 +1,7 @@
import { send } from './signalPlugin'
import store from './index'
var lastPeer // horrible
const configuration = {
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
@@ -6,7 +9,7 @@ const configuration = {
const state = {
name: null,
connections: new Map()
peers: []
}
const getters = {
@@ -17,15 +20,21 @@ const actions = {
setName ({ commit }, name) {
commit('SET_NAME', name)
},
async offer ({ commit }, offer, name) {
commit('CREATE_PEER_CONNECTION', name)
commit('ANSWER', name, offer)
async makeOffer ({ commit }, targetName) {
commit('CREATE_PEER_CONNECTION', targetName)
commit('OFFER', targetName)
},
answer ({ commit }, answer, name) {
commit('OFFER', name, answer)
async offer ({ commit }, { offer, senderName }) {
console.log('offer from ' + senderName)
commit('CREATE_PEER_CONNECTION', senderName)
commit('ANSWER', { target: senderName, offer: offer })
},
candidate ({ commit }, candidate, name) {
commit('ANSWER', name, candidate)
answer ({ commit }, { answer, senderName }) {
console.log('answer from ' + senderName)
commit('FINALIZE', { target: senderName, answer: answer })
},
candidate ({ commit }, { candidate, senderName }) {
commit('CANDIDATE', { target: senderName, candidate: candidate })
},
leave ({ commit }) {
commit('LEAVE')
@@ -40,78 +49,105 @@ const mutations = {
state.name = name
},
CREATE_PEER_CONNECTION (state, target) {
console.log('CREATED PEER CONNECTION')
var connection = new RTCPeerConnection(configuration)
state.connections[target] = connection
console.log('[RTC] create peer connection with ' + target)
var peer = {
name: target,
connection: new RTCPeerConnection(configuration),
dataChannel: null
}
connection.onicecandidate = function (event) {
state.peers.push(peer)
peer.connection.onicecandidate = function (event) {
if (event.candidate) {
send({
type: 'candidate',
name: name,
name: state.name,
target: target,
candidate: event.candidate
data: event.candidate
})
}
}
connection.onnegotiationneeded = function () { handleNegotiationNeededEvent(target) }
connection.onsignalingstatechange = function () { handleSignalingStateChangeEvent(connection) }
connection.oniceconnectionstatechange = function () { handleICEConnectionStateChangeEvent(connection) }
connection.onicegatheringstatechange = function () { handleICEGatheringStateChangeEvent(connection) }
peer.connection.onnegotiationneeded = function () { handleNegotiationNeededEvent(target) }
peer.connection.onsignalingstatechange = function () { handleSignalingStateChangeEvent(peer.connection) }
peer.connection.oniceconnectionstatechange = function () { handleICEConnectionStateChangeEvent(peer.connection) }
peer.connection.onicegatheringstatechange = function () { handleICEGatheringStateChangeEvent(peer.connection) }
},
CREATE_DATA_CHANNEL (state) {
async OFFER (state, target) {
console.log('[RTC] make offer to ' + target)
var peer = state.peers.find(peer => peer.name === target)
peer.dataChannel = peer.connection.createDataChannel('dataChannel')
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
var offer = await peer.connection.createOffer()
send({
type: 'offer',
name: state.name,
target: target,
data: offer
})
await peer.connection.setLocalDescription(offer)
},
ANSWER (state, target, offer) {
var connection = state.connections[target]
async ANSWER (state, { target, offer }) {
console.log('[RTC] answer to ' + target)
var peer = state.peers.find(peer => peer.name === target)
connection.setRemoteDescription(new RTCSessionDescription(offer))
// Permet d'associer le datachannel de la callback au bon peer
lastPeer = peer
var answer = connection.createAnswer()
peer.connection.ondatachannel = handleDataChannelCallback
connection.setLocalDescription(answer)
await peer.connection.setRemoteDescription(new RTCSessionDescription(offer))
var answer = await peer.connection.createAnswer()
await peer.connection.setLocalDescription(answer)
send({
type: 'answer',
name: name,
name: state.name,
target: target,
answer: answer
data: answer
})
},
OFFER (state, target, answer) {
var connection = state.connections[target]
connection.setRemoteDescription(new RTCSessionDescription(answer))
FINALIZE (state, { target, answer }) {
var peer = state.peers.find(peer => peer.name === target)
peer.connection.setRemoteDescription(new RTCSessionDescription(answer))
},
CANDIDATE (state, target, candidate) {
var connection = state.connections[target]
connection.addIceCandidate(new RTCIceCandidate(candidate))
CANDIDATE (state, { target, candidate }) {
var peer = state.peers.find(peer => peer.name === target)
peer.connection.addIceCandidate(new RTCIceCandidate(candidate))
},
LEAVE (state) {
state.connections.forEach((connection) => {
connection.close()
connection = null
state.peers.forEach((peer) => {
peer.connection.close()
})
state.connections = new Map()
state.peers = {}
},
BROADCAST (state, message) {
state.peers.forEach(peer => {
peer.dataChannel.send(message)
})
}
}
function handleICEConnectionStateChangeEvent (connection) {
console.log('ICE CONNECTION CHANGE ' + connection.iceConnectionState)
console.log('[RTC] ice connection change to ' + connection.iceConnectionState)
}
function handleICEGatheringStateChangeEvent (connection) {
console.log('ICE GATHERING CHANGE ' + connection.iceGatheringState)
console.log('[RTC] ice gathering change to ' + connection.iceGatheringState)
}
async function handleNegotiationNeededEvent (target) {
console.log('NEGOTIATION NEEDED FROM ' + target)
console.log('[RTC] negotiation needed from ' + target)
}
async function handleSignalingStateChangeEvent (connection) {
console.log('STATE CHANGED TO : ' + connection.signalingState)
console.log('[RTC] state changed to ' + connection.signalingState)
switch (connection.signalingState) {
case 'closed':
await connection.close()
@@ -119,6 +155,33 @@ async function handleSignalingStateChangeEvent (connection) {
}
}
function handleDataChannelStateChangeEvent () {
console.log('[RTC] data channel state change')
}
function handleDataChannelCallback (event) {
console.log('[RTC] data channel callback ' + event)
var peer = lastPeer
peer.dataChannel = event.channel
peer.dataChannel.onmessage = handleDataChannelMessage
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
store.dispatch('rtc/broadcast', store.state.room.roomStatus)
}
function handleDataChannelMessage (event) {
console.log('[RTC] data channel message ' + event.data)
var data = event.data
switch (data.type) {
case 'status':
store.dispatch('room/setRoomStatus', data.message)
break
case 'vote':
break
}
}
export default {
namespaced: true,
state,

View File

@@ -4,31 +4,33 @@ const connection = new WebSocket('ws://localhost:8181/socket')
export default function createSignalPlugin () {
return store => {
connection.onopen = function () {
console.log('WS connected')
console.log('[WS] connected')
store.dispatch('app/signalConnected')
}
connection.onerror = function (error) {
console.log('WS error ' + error)
console.log('[WS] error ' + error)
store.dispatch('app/signalError', error)
}
connection.onmessage = function (message) {
console.log('WS message', message.data)
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)
console.log('offer from ' + data.name)
store.dispatch('rtc/offer', { offer: data.data, senderName: data.name })
break
case 'answer':
store.dispatch('rtc/answer', data.answer, data.name)
console.log('answer from ' + data.name)
store.dispatch('rtc/answer', { answer: data.data, senderName: data.name })
break
case 'candidate':
store.dispatch('rtc/candidate', data.candidate, data.name)
store.dispatch('rtc/candidate', { candidate: data.data, senderName: data.name })
break
case 'leave':
@@ -47,6 +49,10 @@ export default function createSignalPlugin () {
store.dispatch('app/createRoom', data.message)
break
case 'connectRoom':
store.dispatch('app/connectRoom', data.message)
break
case 'error':
store.dispatch('app/error', data.message)
break
@@ -59,6 +65,6 @@ export default function createSignalPlugin () {
}
export function send (message) {
console.log('WS send', message)
console.log('[WS] send', message)
connection.send(JSON.stringify(message))
}