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 }