122 lines
2.8 KiB
JavaScript
122 lines
2.8 KiB
JavaScript
import CallActions from '../actions/CallActions.js'
|
|
import NotifyActions from '../actions/NotifyActions.js'
|
|
import Peer from './Peer.js'
|
|
import _ from 'underscore'
|
|
import _debug from 'debug'
|
|
import iceServers from '../iceServers.js'
|
|
import { dispatch } from '../store.js'
|
|
import { play } from '../window/video.js'
|
|
|
|
const debug = _debug('peercalls')
|
|
|
|
let peers = {}
|
|
|
|
/**
|
|
* @param {Socket} socket
|
|
* @param {User} user
|
|
* @param {String} user.id
|
|
* @param {Boolean} [initiator=false]
|
|
* @param {MediaStream} [stream]
|
|
*/
|
|
function create ({ socket, user, initiator, stream }) {
|
|
debug('create peer: %s, stream:', user.id, stream)
|
|
dispatch(
|
|
NotifyActions.warn('Connecting to peer...')
|
|
)
|
|
|
|
if (peers[user.id]) {
|
|
dispatch(
|
|
NotifyActions.info('Cleaning up old connection...')
|
|
)
|
|
destroy(user.id)
|
|
}
|
|
|
|
const peer = peers[user.id] = Peer.init({
|
|
initiator: socket.id === initiator,
|
|
stream,
|
|
config: { iceServers }
|
|
})
|
|
|
|
peer.once('error', err => {
|
|
debug('peer: %s, error %s', user.id, err.stack)
|
|
dispatch(
|
|
NotifyActions.error('A peer connection error occurred')
|
|
)
|
|
destroy(user.id)
|
|
})
|
|
|
|
peer.on('signal', signal => {
|
|
debug('peer: %s, signal: %o', user.id, signal)
|
|
|
|
const payload = { userId: user.id, signal }
|
|
socket.emit('signal', payload)
|
|
})
|
|
|
|
peer.once('connect', () => {
|
|
debug('peer: %s, connect', user.id)
|
|
dispatch(
|
|
NotifyActions.warn('Peer connection established')
|
|
)
|
|
play()
|
|
})
|
|
|
|
peer.on('stream', stream => {
|
|
debug('peer: %s, stream', user.id)
|
|
dispatch(CallActions.addStream({
|
|
userId: user.id,
|
|
stream
|
|
}))
|
|
})
|
|
|
|
peer.on('data', object => {
|
|
object = JSON.parse(new window.TextDecoder('utf-8').decode(object))
|
|
debug('peer: %s, message: %o', user.id, object)
|
|
dispatch(
|
|
NotifyActions.info('' + user.id + ': ' + object.message)
|
|
)
|
|
})
|
|
|
|
peer.once('close', () => {
|
|
debug('peer: %s, close', user.id)
|
|
dispatch(
|
|
NotifyActions.error('Peer connection closed')
|
|
)
|
|
dispatch(
|
|
CallActions.removeStream(user.id)
|
|
)
|
|
|
|
// make sure some other peer with same id didn't take place between calling
|
|
// `destroy()` and `close` event
|
|
if (peers[user.id] === peer) delete peers[user.id]
|
|
})
|
|
}
|
|
|
|
function get (userId) {
|
|
return peers[userId]
|
|
}
|
|
|
|
function getIds () {
|
|
return _.map(peers, (peer, id) => id)
|
|
}
|
|
|
|
function clear () {
|
|
debug('clear')
|
|
_.each(peers, (_, userId) => destroy(userId))
|
|
peers = {}
|
|
}
|
|
|
|
function destroy (userId) {
|
|
debug('destroy peer: %s', userId)
|
|
let peer = peers[userId]
|
|
if (!peer) return debug('peer: %s peer not found', userId)
|
|
peer.destroy()
|
|
delete peers[userId]
|
|
}
|
|
|
|
function message (message) {
|
|
message = JSON.stringify({ message })
|
|
_.each(peers, peer => peer.send(message))
|
|
}
|
|
|
|
module.exports = { create, get, getIds, destroy, clear, message }
|