Simple-peer: Initiator emits multiple signals on returning signal

Created on 15 May 2020  Â·  4Comments  Â·  Source: feross/simple-peer

I am trying to create a simple group video chat app with Electron-vue but I am having a problem whereby the peer (Peer1) that initiated a call emits multiple signals from the peer (Peer2) that accepted the call. This only happens when peer1 accepts the signal from peer2.

Below is both the server and client code:

SERVER

import express from 'express'
import cors from 'cors'
import http from 'http'
import socket from 'socket.io'

const app = express()

//initialize a simple http server
const server = http.createServer(app)

const io = socket(server)

// Middleware
app.use(cors({
  origin: '*'
}))
app.use(express.json())
app.use(express.urlencoded({ extended: false }));
// app.use(express.static('src'));

const users: any = {};
// const socketToRoom: any = {};

io.on('connection', socket => {
  console.log('socket connection establish')

  socket.on('joinRoom', room => {
    console.log('joined room', room)

    if (!users[room]) {
      users[room] = [socket.id]
    } else {
      users[room].push(socket.id)
    }

    const usersInRoom = users[room].filter((id: any) => id !== socket.id)

    socket.emit('allUsersInRoom', usersInRoom)
  })

  socket.on('callAUser', payload => {
    console.log('calling a user...')
    const { caller, callee, signal } = payload

    io.to(callee).emit('incomingCall', { caller: caller, signal:signal })
  })

  socket.on('sendHandshake', payload => {
    console.log('sending handshake...')
    const { caller, signal } = payload

    io.to(caller).emit('recievedHandshake', { signal: signal, id: socket.id })
  })
});

(async () => {
  try {
    server.listen(3000, () => console.log(`Server listening on port ${3000}`))
  } catch (error) {
    console.log('Could not connect to database', error)
  }
})()
import io from 'socket.io-client'
import Peer from 'simple-peer'

import Person from '../components/room/partials/Peer'
import Controls from '../components/room/partials/Controls'

export default {
  data () {
    return {
      room: 'sjk123khs',
      peers: [],
      socket: ''
    }
  },
  components: {
    Person,
    Controls
  },
  methods: {
    callPeer (userToCall, caller, stream) {
      const peer = new Peer({
        initiator: true,
        trickle: false,
        stream: stream
      })

      // THIS ALONE RUNS MULTIPLE TIME
      peer.on('signal', signal => {
        console.log('call a user(FRONTEND)')
        this.socket.emit('callAUser', { caller: caller, callee: userToCall, signal: signal })
      })

      this.socket.on('recievedHandshake', payload => {
        console.log('recieved handshake',  payload)

        const { signal } = payload

        peer.signal(signal) // THIS MAKE THE peer.on('signal') TO EXECUTE MULTIPLE TIMES
      })

      return peer
    },
    acceptCall (caller, incomingSignal, stream) {
      const peer = new Peer({
        initiator: false,
        trickle: false,
        stream: stream
      })

      // THIS ALWAYS RUN TWICE
      peer.on('signal', signal => {
        console.log('handshake')
        this.socket.emit('sendHandshake', { caller: caller, signal: signal })
      })

      peer.signal(incomingSignal)

      return peer
    }
  },
  created () {
    this.socket = io('http://localhost:3000')

    navigator.mediaDevices
      .getUserMedia({
        video: true,
        audio: true
      })
      .then(stream => {
        this.$refs.me.srcObject = stream

        this.socket.emit('joinRoom', this.room)
        this.socket.on('allUsersInRoom', users => {
          const peers = []

          users.forEach(user => {
            const peer = this.callPeer(user, this.socket.id, stream)
            peers.push({ peer, id: user })
          })

          // console.log(users)
          this.peers = peers
        })
        this.socket.on('incomingCall', payload => {
          console.log('incoming call to a user...')

          const { caller, signal } = payload

          const peer = this.acceptCall(caller, signal, stream)

          this.peers = [...this.peers, { peer, id: caller }]
        })
      })
  }
}
bug help wanted need reproduction

Most helpful comment

I think it is a bug on version 9.7.2. After downgrading to version 9.6.2 it works normally.

All 4 comments

I think you're somehow attaching the listener for the 'signal' event twice. I'm not familiar with the frameworks you're using.

I'm closing this issue since there's no bug to fix here, but feel free to continue discussion! ✨

I think it is a bug on version 9.7.2. After downgrading to version 9.6.2 it works normally.

I ran into the same issue and did some digging. Version 9.7.0 already causes the same issue for me. I looked some of the commits between 9.6.2 and 9.7.0 and found this: https://github.com/feross/simple-peer/commit/947d873540ee337f990ce00a341de4a7aea1cacc

I noticed that when I undo the changes from that commit, the issue is gone.

I followed this (https://github.com/coding-with-chaim/group-video-final) repository pretty closely when doing my implementation, and tested my "theory" on that repository code, and the same thing happened.

Could this information help to maybe solve what is the actual culprit of this issue? What do you think @feross :)

I'll re-open this so someone can investigate further and hopefully send a PR.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adammw picture adammw  Â·  5Comments

Applicafroguy picture Applicafroguy  Â·  3Comments

alexmarion picture alexmarion  Â·  4Comments

jimmywarting picture jimmywarting  Â·  3Comments

saagarbethi picture saagarbethi  Â·  4Comments