Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE] Getting a UnhandledPromiseRejectionWarning when calling .accept() #32

Open
OmarB97 opened this issue Dec 29, 2020 · 3 comments
Open

Comments

@OmarB97
Copy link

OmarB97 commented Dec 29, 2020

Hi, I'm trying to do a p2p connection where one peer is the browser, and the other peer is the server. So basically, my browser client code is handling a SimpleSignalClient, and the server is handling both the SimpleSignalServer and the other SimpleSignalClient. The reason is because I'm trying to pass my video/audio stream (mediaStream) from browser to server, which once I have established that connection I will then do some more work on the server side to eventually get it converted + sent to a RTMP endpoint. The issue is that when I try to establish this relationship, when I have all the code set up with the discover/request/connect/etc, when my server's SignalClient calls request.accept({}, { wrtc: wrtc }) inside the .on('request, ...) then I get this error:

(node:35795) UnhandledPromiseRejectionWarning: #
(Use node --trace-warnings ... to show where the warning was created)
(node:35795) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:35795) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

When I use a try/catch then I get this: metadata: {code: "ERR_CONNECTION_TIMEOUT"}

Is there a reason why this is failing to connect? Is there something else I'm missing here? I can share more of my code if it helps. Thanks!

Code snippets:

Server's SignalServer:

var signalServer = require('simple-signal-server')(io);
var signalClient = require('simple-signal-client')(socket);

...

signalServer.on('discover', (request) => {
  request.discover(signalClient.socket.id);  
})

signalServer.on('disconnect', (socket) => {
})

signalServer.on('request', (request) => {
  request.forward();
})

Server's SignalClient:

  signalClient.on('request', (request) => {
    try {
      request.accept({}, { wrtc: wrtc }) // Accept the incoming request
    } catch (e) {
      console.error(e);
    } 
  })

Client's SignalClient:

    import io from 'socket.io-client';
    import SimpleSignalClient from 'simple-signal-client'; 

    ...

    const signalClient = new SimpleSignalClient(io('localhost:1234'));
      signalClient.on('discover', (id) => {
        signalClient.connect(id); // connect to target client
      });

      signalClient.discover();

@OmarB97 OmarB97 changed the title Getting a UnhandledPromiseRejectionWarning when calling .accept() [ISSUE] Getting a UnhandledPromiseRejectionWarning when calling .accept() Dec 29, 2020
@Densyakun
Copy link

Densyakun commented Nov 23, 2022

Hi, I am developing a p2p connection between browser and server and am experiencing similar problems.

In my case, I am getting an "{ code: ERR_CONNECTION_TIMEOUT }" error in signalClient.connect().

If the SimpleSignalClient.prototype._onSafeConnect() function is executed correctly in .connect or .accept, it seems to resolve the issue.

I too am looking for a solution to this problem.

server.js:

const { createServer } = require('http')
const { Server } = require("socket.io")

module.exports = function (port) {
  const server = createServer()

  const io = new Server(server)
  const signalServer = require('simple-signal-server')(io)

  signalServer.on('discover', (request) => {
    console.log(`server:discover`)
    request.discover([])
  })

  signalServer.on('request', (request) => {
    console.log(`server:request`)
    request.forward()
  })

  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
}

client,js:

const SimpleSignalClient = require('simple-signal-client')
const io = require('socket.io-client')

module.exports = function (port) {
  const socket = io(`http://localhost:${port}`, { secure: true })
  const signalClient = new SimpleSignalClient(socket)

  signalClient.on('discover', async () => {
    console.log('client:discover')
    await signalClient.connect('', undefined, { wrtc: require('wrtc') }).catch(reason => console.error(`err:discover ${JSON.stringify(reason)}`))
  })

  signalClient.on('request', async (request) => {
    console.log('client:request')
    await request.accept().catch(reason => console.error(`err:request ${JSON.stringify(reason)}`))
  })

  signalClient.discover()
}

index.js:

const client = require('./client')

const port = parseInt(process.env.PORT || '3000')

require('./server')(port)

client(port)

console:

> node .\index.js
> Ready on http://localhost:3000
server:discover
client:discover
server:request
err:discover {"metadata":{"code":"ERR_CONNECTION_TIMEOUT"}}

@Densyakun
Copy link

The usage of simple-signal was incorrect.
After modifying the code, the error is no longer thrown.

server.js:

  • robotPeer is equivalent to Server's SignalClient
const { createServer } = require('http')
const { Server } = require("socket.io")

let robotPeerPassword
function resetRobotPeerPassword() {
  robotPeerPassword = ''
  for (var i = 0; i < 6; i++)
    robotPeerPassword += String.fromCodePoint(Math.floor(Math.random() * 0x10FFFF))
}
resetRobotPeerPassword()

function startRobotClient(port, password) {
  const SimpleSignalClient = require('simple-signal-client')
  const io = require('socket.io-client')
  const wrtc = require('wrtc')

  const socket = io(`http://localhost:${port}`, { secure: true })
  const signalClient = new SimpleSignalClient(socket)

  signalClient.on('discover', async (id) => {
    console.log('robotClient:discover')
    await signalClient.connect(id, undefined, { wrtc: wrtc })
  })

  signalClient.on('request', async (request) => {
    console.log('robotClient:request')
    const { peer } = await request.accept(undefined, { wrtc: wrtc })

    peer.on('data', data => {
      console.log('got a message: ' + data)
    })
  })

  signalClient.discover(password)
}

let clientRequest

module.exports = function (port) {
  const server = createServer()

  const io = new Server(server)
  const signalServer = require('simple-signal-server')(io)

  signalServer.on('discover', (request) => {
    console.log(`server:discover`)

    const isRobotPeer = request.discoveryData === robotPeerPassword
    if (!isRobotPeer) {
      clientRequest = request
      startRobotClient(port, robotPeerPassword)
    } else {
      resetRobotPeerPassword()

      clientRequest.discover(request.socket.id)
      request.discover(clientRequest.socket.id)
    }
  })

  signalServer.on('request', (request) => {
    console.log(`server:request`)
    request.forward()
  })

  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
}

client.js:

const SimpleSignalClient = require('simple-signal-client')
const io = require('socket.io-client')
const wrtc = require('wrtc')

module.exports = function (port) {
  const socket = io(`http://localhost:${port}`, { secure: true })
  const signalClient = new SimpleSignalClient(socket)

  signalClient.on('discover', async (id) => {
    console.log('client:discover')
    const { peer } = await signalClient.connect(id, undefined, { wrtc: wrtc })

    peer.on('connect', () => {
      peer.send('how is it going?')
    })
  })

  signalClient.on('request', async (request) => {
    console.log('client:request')
    await request.accept(undefined, { wrtc: wrtc })
  })

  signalClient.discover()
}

index.js:

const port = parseInt(process.env.PORT || '3000')

require('./server')(port)
require('./client')(port)

console:

> node .\index.js
> Ready on http://localhost:3000
server:discover
server:discover
client:discover
robotClient:discover
server:request
server:request
robotClient:request
client:request
got a message: how is it going?
  1. SignalServer will be opened
  2. Client's SignalClient connect to SignalServer (Do not execute request.discover function here!)
  3. Save Client's SignalClient request
  4. Start Server's SignalClient
  5. Server's SignalClient connect to SignalServer
  6. Send the partner id to Client's SignalClient and Server's SignalClient with request.discover
  7. Try to connect to the partner peer with signalClient.connect
  8. SignalServer allows connection with request.forward
  9. SignalClients allow connections (client:request, robotClient:request)
  10. send data from Client's SignalClient to Server's SignalClient by peer.on('connect')

@Densyakun
Copy link

To support multiple SignalClient, start the Server's SignalClient after opening SignalServer.

server.js:

const { createServer } = require('http')
const { Server } = require("socket.io")

let robotPeerPassword = ''
for (var i = 0; i < 6; i++)
  robotPeerPassword += String.fromCodePoint(Math.floor(Math.random() * 0x10FFFF))

function startRobotClient(port, password) {
  const SimpleSignalClient = require('simple-signal-client')
  const io = require('socket.io-client')
  const wrtc = require('wrtc')

  const socket = io(`http://localhost:${port}`, { secure: true })
  const signalClient = new SimpleSignalClient(socket)

  signalClient.on('discover', async (id) => {
    console.log('robotClient:discover')
    await signalClient.connect(id, undefined, { wrtc: wrtc })
  })

  signalClient.on('request', async (request) => {
    console.log('robotClient:request')
    const { peer } = await request.accept(undefined, { wrtc: wrtc })

    peer.on('data', data => {
      console.log('got a message: ' + data)
    })
  })

  signalClient.discover(password)
}

let robotPeerRequest

module.exports = function (port) {
  const server = createServer()

  const io = new Server(server)
  const signalServer = require('simple-signal-server')(io)

  signalServer.on('discover', (request) => {
    console.log(`server:discover`)

    const isRobotPeer = robotPeerPassword && request.discoveryData === robotPeerPassword
    if (!isRobotPeer) {
      request.discover(robotPeerRequest.socket.id)
      robotPeerRequest.discover(request.socket.id)
    } else {
      robotPeerPassword = ''
      robotPeerRequest = request
    }
  })

  signalServer.on('request', (request) => {
    console.log(`server:request`)
    request.forward()
  })

  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
    startRobotClient(port, robotPeerPassword)
  })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants