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

Documentation on hosting in multiple servers #1

Closed
macrobian88 opened this issue Aug 17, 2023 · 38 comments
Closed

Documentation on hosting in multiple servers #1

macrobian88 opened this issue Aug 17, 2023 · 38 comments

Comments

@macrobian88
Copy link

Hi,

Can you provide more details on the steps in config.js file to connect the master and slave nodes in different hosts.

The parameters
API_HOST = '127.0.0.1'
LISTEN_HOST = ::

are confusing while configuring the server in multi host environment.

@woody146
Copy link
Owner

woody146 commented Aug 19, 2023

Thanks, this is my mistake. I have removed LISTEN_HOST env

Client only call api of master server, then master server will call api of slave server. You can check in examples/rooms folder. In example, nextjs server create a proxy to master server

async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:3010/:path*',
      },
    ];
  },

@macrobian88
Copy link
Author

macrobian88 commented Aug 20, 2023

Thanks for the response.

Let me elaborate more on the config file so that it may help others who is looking for the same kind of solution.

I am running the applicaiton/ master from 3 different machines in same network.

  1. masterserver 192.168.0.2
  2. Slave Producer 192.168.0.3
  3. Slave consumer 192.168.0.4

and in config of master server has the

API_HOST = '127.0.0.1' // in this case which IP address do I need to mention.

As per my understanding I can run the applicaiton in 3 different hosts/machine as long as they are in the same local network.

@woody146
Copy link
Owner

So, I understand you confusion. I have changed API_HOST to LISTEN_HOST
And, you can run master server, slave Producer, slave consumer in different hosts/machines. In your case:

  1. master server 192.168.0.2 => LISTEN_HOST = '192.168.0.2'
  2. Slave Producer 192.168.0.3 => LISTEN_HOST = '192.168.0.3'
  3. Slave consumer 192.168.0.4 => LISTEN_HOST = '192.168.0.4'

@macrobian88
Copy link
Author

macrobian88 commented Aug 22, 2023

Yes added the LISTEN_HOST in 3 different machines.

master server 192.168.0.2 => LISTEN_HOST = '192.168.0.2' ==> UI is running in port 3000
Slave Producer 192.168.0.3 => LISTEN_HOST = '192.168.0.3'
Slave consumer 192.168.0.4 => LISTEN_HOST = '192.168.0.4'

All 3 instances are in same VPC subnet and same region.

But getting 500 error while creating the room from frontend.

Got following errorlog from master server.

===============================================================================
{"level":30,"time":1692693341304,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-1","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":43874},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693341337,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-1","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":43874},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693341341,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-1","res":{"statusCode":500},"responseTime":35.96405506134033,"msg":"request completed"}
{"level":30,"time":1692693348564,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-2","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":43890},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693348571,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-2","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":43890},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693348572,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-2","res":{"statusCode":500},"responseTime":6.983705043792725,"msg":"request completed"}
{"level":30,"time":1692693350669,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-3","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37812},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693350678,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-3","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37812},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693350678,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-3","res":{"statusCode":500},"responseTime":9.03496503829956,"msg":"request completed"}
{"level":30,"time":1692693354736,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-4","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37822},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693354742,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-4","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37822},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693354742,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-4","res":{"statusCode":500},"responseTime":5.9319069385528564,"msg":"request completed"}
{"level":30,"time":1692693356933,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-5","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37826},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693356940,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-5","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":37826},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693356941,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-5","res":{"statusCode":500},"responseTime":7.8793439865112305,"msg":"request completed"}
{"level":30,"time":1692693434848,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-6","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44894},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693434866,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-6","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44894},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693434867,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-6","res":{"statusCode":500},"responseTime":18.233872890472412,"msg":"request completed"}
{"level":30,"time":1692693436743,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-7","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44896},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693436749,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-7","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44896},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693436749,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-7","res":{"statusCode":500},"responseTime":5.718765020370483,"msg":"request completed"}
{"level":30,"time":1692693438276,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-8","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44910},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1692693438281,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-8","req":{"method":"POST","url":"/rooms","hostname":"localhost:3010","remoteAddress":"127.0.0.1","remotePort":44910},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692693438281,"pid":109428,"hostname":"ip-172-31-37-75","reqId":"req-8","res":{"statusCode":500},"responseTime":5.48016095161438,"msg":"request completed"}

==============================================================================

@woody146
Copy link
Owner

"msg":"fetch is not defined"

Do you run npm run install in examples/rooms/

@macrobian88
Copy link
Author

I did
npm install
npm run buil
sudo npm start.

I am accesing the applicaiton from http://ip:3000

@woody146
Copy link
Owner

Does content of file dist/run_master.js have import 'node-fetch';

@macrobian88
Copy link
Author

macrobian88 commented Aug 22, 2023

Yes it has.

import 'node-fetch';
import apiRouters from './apis/master.js';
import { startServer } from './utils/index.js';
startServer(apiRouters);
//# sourceMappingURL=run_master.js.map

Using node v16.20.1 npm 8.19.4 in ubuntu 20.04 AWS Ec2 instance.

@woody146
Copy link
Owner

You should remove node_modules folder and package-lock.json. Then reinstall mediasoup cluster with npm ic

@macrobian88
Copy link
Author

macrobian88 commented Aug 22, 2023

Still same.

I have Postgres in RDS and all microservices are registering in media_worker table.

I am getting this below log in UI

POST http://IP:3000/api/rooms 500 (Internal Server Error)

====================================
Failed to proxy http://localhost:3010/rooms Error: connect ECONNREFUSED 127.0.0.1:3010
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3010
}
Error: connect ECONNREFUSED 127.0.0.1:3010
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3010
}

=========================================================

@woody146
Copy link
Owner

woody146 commented Aug 22, 2023

Must update examples/rooms/next.config.js to

async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://[YOUR_MASTER_IP]:3010/:path*',
      },
    ];
  },

@macrobian88
Copy link
Author

macrobian88 commented Aug 22, 2023

Added.

async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://[PUBLIC_MASTER_IP]:3010/:path*',
},
];
},

Cleared localcache from browser.

still getting page-e0c2a778d0d27552.js:1 POST http://IP:3000/api/rooms 500 (Internal Server Error). //not sure why it is hitting 3000 port

In master server .env
LISTEN_HOST = '0.0.0.0' ==> if i give PUBLIC ACCESS IP then getting error

Error: listen EADDRNOTAVAIL: address not available PUBLIC ACCESS IP:3010
at Server.setupListenHandle [as _listen2] (node:net:1446:21)
at listenInCluster (node:net:1511:12)
at doListen (node:net:1660:7)
at processTicksAndRejections (node:internal/process/task_queues:84:21) {
code: 'EADDRNOTAVAIL',
errno: -99,
syscall: 'listen',
address: ' PUBLIC ACCESS IP',
port: 3010
}

in master server following services are running.

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:36343 0.0.0.0:* LISTEN 110733/node
tcp 0 0 0.0.0.0:3010 0.0.0.0:* LISTEN 110827/node
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 110722/node
tcp 0 0 127.0.0.1:34769 0.0.0.0:* LISTEN 110744/node
tcp 0 0 0.0.0.0:38457 0.0.0.0:* LISTEN 110733/node

ERROR LOG IN MASTER 3010

=============================
{"level":50,"time":1692697344346,"pid":110867,"hostname":"ip-172-31-37-75","reqId":"req-8","req":{"method":"POST","url":"/rooms","hostname":"PUBLIC_IP:3010","remoteAddress":"PUBLIC_IP","remotePort":51896},"res":{"statusCode":500},"err":{"type":"ReferenceError","message":"fetch is not defined","stack":"ReferenceError: fetch is not defined\n at fetchApi (file:///opt/master/mediasoup-cluster/dist/utils/api.js:29:5)\n at RoomService.create (file:///opt/master/mediasoup-cluster/dist/services/room.js:9:30)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"msg":"fetch is not defined"}
{"level":30,"time":1692697344346,"pid":110867,"hostname":"ip-172-31-37-75","reqId":"req-8","res":{"statusCode":500},"responseTime":18.693245887756348,"msg":"request completed"}

================================================

mediasoup ip config

MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
{
"ip": "172.31.37.197",
"announcedIp": "PUBLIC_IP"
},
{
"ip": "172.31.37.15",
"announcedIp": "PUBLIC_IP"
},
{
"ip": "172.31.37.75",
"announcedIp":"PUBLIC_IP"
}

@woody146
Copy link
Owner

woody146 commented Aug 23, 2023

Do you try to fix error fetch is not defined

You should remove node_modules folder and package-lock.json. Then reinstall mediasoup cluster with npm ic

@macrobian88
Copy link
Author

macrobian88 commented Aug 23, 2023

I did reinstalling the node_modules and removed the package-lock.json file before npm installation.

Still facing the same issue.

Can you update the .env sample file once for a 3 host cluster.

I will redeploy once again and update you.

@woody146
Copy link
Owner

woody146 commented Aug 23, 2023

Your error is caused by npm installation, not involved in .env file.
You should fix error fetch is not defined first
Or you try to use node v18

@macrobian88
Copy link
Author

macrobian88 commented Aug 23, 2023

Upgraded the node version to 18 and node-fetch error resolved.

Now I am getting port bind failed error.

All 3 servers are in same subnet and UDP ports are open.

======================
{"statusCode":500,"error":"Internal Server Error","message":"port bind failed due to address not available [transport:udp, ip:'172.31.33.15', port:24723, attempt:1/20001] [method:router.createWebRtcTransport]"}

following is the .env of servers,

master server //do we need MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS in this server as it is master http server??
LISTEN_HOST = '172.31.33.75'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "172.31.33.197", "announcedIp": "54.xx.xx.yy" }, { "ip": "172.31.33.15", "announcedIp": "52.xx.xx.yy" }]'

in consumer server
LISTEN_HOST = '172.31.33.15'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "172.31.33.197", "announcedIp": "54.xx.xx.yy" }, { "ip": "172.31.33.15", "announcedIp": "52.xx.xx.yy" }]'

in producer server
LISTEN_HOST = '172.31.33.197'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "172.31.33.197", "announcedIp": "54.xx.xx.yy" }, { "ip": "172.31.33.15", "announcedIp": "52.xx.xx.yy" }]'

@woody146
Copy link
Owner

You don't need set MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS in .env file for master server

You should set env for slave server as below

MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
   {
      "ip": [YOUR_PUBLIC_IP], 
      "announcedIp": null
   }
]'

@macrobian88
Copy link
Author

macrobian88 commented Aug 23, 2023

Did above changes but still getting the same issue.

In 52.xx.xx.yy there is nothing running on port 32372

{"statusCode":500,"error":"Internal Server Error","message":"port bind failed due to address not available [transport:udp, ip:'52.xx.xx.yy', port:32372, attempt:1/20001] [method:router.createWebRtcTransport]"}

@woody146
Copy link
Owner

Is 52.xx.xx.yy public ip of your slave server?
You can check document of mediasoup

@macrobian88
Copy link
Author

Yes. It is the PUBLIC IP of the slave consumer server where the consumer is running.

I gone through the document. I think I have understood and implemented same. But still I am seeing the issue. the UDP and TCP ports in that range are allowed and accessable from public.

@macrobian88
Copy link
Author

macrobian88 commented Aug 23, 2023

Do you have any .env config for the multiple host or can you please help me in confirming whether the following configuration is correct.

in master server
LISTEN_HOST = 'PUBLIC_IP_OF_MASTER_SERVER'

in consumer server
LISTEN_HOST = 'PUBLIC_IP_OF_SLAVE_CONSUMER'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "PUBLIC_IP_OF_SLAVE_PRODUCER", "announcedIp": null }, { "ip": "PUBLIC_IP_OF_SLAVE_CONSUMER", "announcedIp": null }]'

in producer server
LISTEN_HOST = 'PUBLIC_IP_OF_SLAVE_PRODUCER'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "PUBLIC_IP_OF_SLAVE_PRODUCER", "announcedIp": null }, { "ip": "PUBLIC_IP_OF_SLAVE_CONSUMER", "announcedIp": null }]'

@woody146
Copy link
Owner

You should set

in consumer server
LISTEN_HOST = 'IP_IN_LAN_NETWORK_OF_SLAVE_CONSUMER' // only for master call api
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "PUBLIC_IP_OF_SLAVE_CONSUMER", "announcedIp": null }]'

in producer server
LISTEN_HOST = 'IP_IN_LAN_NETWORK_OF_SLAVE_PRODUCER' // only for master call api'
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[{ "ip": "PUBLIC_IP_OF_SLAVE_PRODUCER", "announcedIp": null }]'

Example

  1. Master server: lan ip 192.168.1.1, public ip 8.8.8.1
LISTEN_HOST = 8.8.8.1
  1. Slave consumer: lan ip 192.168.1.2 public ip 8.8.8.2
LISTEN_HOST = 192.168.1.2
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
   {
      "ip": "8.8.8.2",
      "announcedIp": null
   }
]'
  1. Slave producer: lan ip 192.168.1.3 public ip 8.8.8.3
LISTEN_HOST = 192.168.1.3
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
   {
      "ip": "8.8.8.3",
      "announcedIp": null
   }
]'

@macrobian88
Copy link
Author

Thanks for the update.

It worked after making the following change

LISTEN_HOST = 192.168.1.3
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
{
"ip": "8.8.8.3",
"announcedIp": "8.8.8.3"
}
]'

Just curious on how can we add/scale the slave producer or consumer? Is it possible.

@woody146
Copy link
Owner

woody146 commented Aug 24, 2023

Yes it's scalable. You only add producer or consumer server with above config
After new producer/ consumer is started, it will insert data to table media_worker. So master server recognizes it automatically

@macrobian88
Copy link
Author

Thank you so much @woody146 for the elaborated help on this.

This is a wonderful project which you created.

Cheers :)

@huangqingbiao8831
Copy link

mediasoup-cluster@4.1.1 start:slave:producer
cross-env PORT=3011 SLAVE_FOR=producer node dist/run_slave.js

query: SELECT * FROM current_schema()
query: CREATE EXTENSION IF NOT EXISTS "uuid-ossp"
query: SELECT version();
query: START TRANSACTION
query: SELECT * FROM current_schema()
query: SELECT * FROM current_database()
query: SELECT "table_schema", "table_name" FROM "information_schema"."tables" WHERE ("table_schema" = 'public' AND "table_name" = 'media_consumer') OR ("table_schema" = 'public' AND "table_name" = 'media_producer') OR ("table_schema" = 'public' AND "table_name" = 'media_transport') OR ("table_schema" = 'public' AND "table_name" = 'media_router') OR ("table_schema" = 'public' AND "table_name" = 'media_room') OR ("table_schema" = 'public' AND "table_name" = 'media_worker')
query: SELECT TRUE FROM information_schema.columns WHERE table_name = 'pg_class' and column_name = 'relispartition'
query: SELECT columns.*, pg_catalog.col_description(('"' || table_catalog || '"."' || table_schema || '"."' || table_name || '"')::regclass::oid, ordinal_position) AS description, ('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype", pg_catalog.format_type("col_attr"."atttypid", "col_attr"."atttypmod") AS "format_type" FROM "information_schema"."columns" LEFT JOIN "pg_catalog"."pg_attribute" AS "col_attr" ON "col_attr"."attname" = "columns"."column_name" AND "col_attr"."attrelid" = ( SELECT "cls"."oid" FROM "pg_catalog"."pg_class" AS "cls" LEFT JOIN "pg_catalog"."pg_namespace" AS "ns" ON "ns"."oid" = "cls"."relnamespace" WHERE "cls"."relname" = "columns"."table_name" AND "ns"."nspname" = "columns"."table_schema" ) WHERE ("table_schema" = 'public' AND "table_name" = 'media_consumer') OR ("table_schema" = 'public' AND "table_name" = 'media_producer') OR ("table_schema" = 'public' AND "table_name" = 'media_transport') OR ("table_schema" = 'public' AND "table_name" = 'media_router') OR ("table_schema" = 'public' AND "table_name" = 'media_room') OR ("table_schema" = 'public' AND "table_name" = 'media_worker')
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "cnst"."conname" AS "constraint_name", pg_get_constraintdef("cnst"."oid") AS "expression", CASE "cnst"."contype" WHEN 'p' THEN 'PRIMARY' WHEN 'u' THEN 'UNIQUE' WHEN 'c' THEN 'CHECK' WHEN 'x' THEN 'EXCLUDE' END AS "constraint_type", "a"."attname" AS "column_name" FROM "pg_constraint" "cnst" INNER JOIN "pg_class" "t" ON "t"."oid" = "cnst"."conrelid" INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "cnst"."connamespace" LEFT JOIN "pg_attribute" "a" ON "a"."attrelid" = "cnst"."conrelid" AND "a"."attnum" = ANY ("cnst"."conkey") WHERE "t"."relkind" IN ('r', 'p') AND (("ns"."nspname" = 'public' AND "t"."relname" = 'media_consumer') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_producer') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_transport') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_router') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_room') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_worker'))
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "i"."relname" AS "constraint_name", "a"."attname" AS "column_name", CASE "ix"."indisunique" WHEN 't' THEN 'TRUE' ELSE'FALSE' END AS "is_unique", pg_get_expr("ix"."indpred", "ix"."indrelid") AS "condition", "types"."typname" AS "type_name" FROM "pg_class" "t" INNER JOIN "pg_index" "ix" ON "ix"."indrelid" = "t"."oid" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "t"."oid" AND "a"."attnum" = ANY ("ix"."indkey") INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "t"."relnamespace" INNER JOIN "pg_class" "i" ON "i"."oid" = "ix"."indexrelid" INNER JOIN "pg_type" "types" ON "types"."oid" = "a"."atttypid" LEFT JOIN "pg_constraint" "cnst" ON "cnst"."conname" = "i"."relname" WHERE "t"."relkind" IN ('r', 'p') AND "cnst"."contype" IS NULL AND (("ns"."nspname" = 'public' AND "t"."relname" = 'media_consumer') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_producer') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_transport') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_router') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_room') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'media_worker'))
query: SELECT "con"."conname" AS "constraint_name", "con"."nspname" AS "table_schema", "con"."relname" AS "table_name", "att2"."attname" AS "column_name", "ns"."nspname" AS "referenced_table_schema", "cl"."relname" AS "referenced_table_name", "att"."attname" AS "referenced_column_name", "con"."confdeltype" AS "on_delete", "con"."confupdtype" AS "on_update", "con"."condeferrable" AS "deferrable", "con"."condeferred" AS "deferred" FROM ( SELECT UNNEST ("con1"."conkey") AS "parent", UNNEST ("con1"."confkey") AS "child", "con1"."confrelid", "con1"."conrelid", "con1"."conname", "con1"."contype", "ns"."nspname", "cl"."relname", "con1"."condeferrable", CASE WHEN "con1"."condeferred" THEN 'INITIALLY DEFERRED' ELSE 'INITIALLY IMMEDIATE' END as condeferred, CASE "con1"."confdeltype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confdeltype", CASE "con1"."confupdtype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confupdtype" FROM "pg_class" "cl" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_constraint" "con1" ON "con1"."conrelid" = "cl"."oid" WHERE "con1"."contype" = 'f' AND (("ns"."nspname" = 'public' AND "cl"."relname" = 'media_consumer') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'media_producer') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'media_transport') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'media_router') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'media_room') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'media_worker')) ) "con" INNER JOIN "pg_attribute" "att" ON "att"."attrelid" = "con"."confrelid" AND "att"."attnum" = "con"."child" INNER JOIN "pg_class" "cl" ON "cl"."oid" = "con"."confrelid" AND "cl"."relispartition" = 'f'INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_attribute" "att2" ON "att2"."attrelid" = "con"."conrelid" AND "att2"."attnum" = "con"."parent"
query: SELECT "udt_schema", "udt_name" FROM "information_schema"."columns" WHERE "table_schema" = 'public' AND "table_name" = 'media_router' AND "column_name"='pipedProducers'
query: SELECT "e"."enumlabel" AS "value" FROM "pg_enum" "e" INNER JOIN "pg_type" "t" ON "t"."oid" = "e"."enumtypid" INNER JOIN "pg_namespace" "n" ON "n"."oid" = "t"."typnamespace" WHERE "n"."nspname" = 'public' AND "t"."typname" = 'uuid'
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = 'public' AND "table_name" = 'typeorm_metadata'
query: COMMIT
{"level":30,"time":1719308345933,"pid":4090,"hostname":"huangqb-KVM","msg":"Server listening at http://10.21.19.84:3011"}
✅ App ready: http://10.21.19.84:3011
/home/huangqb/mediasoup/mediasoup-cluster/node_modules/mediasoup/node/lib/Worker.js:145
this.emit('@failure', new Error([pid:${this.#pid}, code:${code}, signal:${signal}]));
^

Error: [pid:4101, code:null, signal:SIGSEGV]
at ChildProcess. (/home/huangqb/mediasoup/mediasoup-cluster/node_modules/mediasoup/node/lib/Worker.js:145:43)
at ChildProcess.emit (node:events:512:28)
at ChildProcess._handle.onexit (node:internal/child_process:293:12)

Node.js v19.7.0
I got above error,could you give me some advise

@woody146
Copy link
Owner

mediasoup-cluster@4.1.1 start:slave:producer
Error: [pid:4101, code:null, signal:SIGSEGV] at ChildProcess. (/home/huangqb/mediasoup/mediasoup-cluster/node_modules/mediasoup/node/lib/Worker.js:145:43) at ChildProcess.emit (node:events:512:28) at ChildProcess._handle.onexit (node:internal/child_process:293:12)

Node.js v19.7.0 I got above error,could you give me some advise

You can check at this link https://www.geeksforgeeks.org/segmentation-fault-sigsegv-vs-bus-error-sigbus/. Maybe your problem is your hardware

@huangqingbiao8831
Copy link

thinks for your patience,I solved the above error by upgraded nodejs,but I got another error.

{"level":30,"time":1719386132999,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-c","req":{"method":"POST","url":"/rooms","hostname":"10.21.19.136:3010","remoteAddress":"10.21.19.136","remotePort":55712},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount", "worker"."errorCount" AS "worker_errorCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1719386133049,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-c","req":{"method":"POST","url":"/rooms","hostname":"10.21.19.136:3010","remoteAddress":"10.21.19.136","remotePort":55712},"res":{"statusCode":500},"err":{"type":"TypeError","message":"fetch failed: connect ECONNREFUSED 10.21.19.136:3011","stack":"TypeError: fetch failed\n at node:internal/deps/undici/undici:12500:13\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async RoomService.create (file:///home/huangqb/mediasoup-cluster/dist/services/room.js:9:24)\ncaused by: Error: connect ECONNREFUSED 10.21.19.136:3011\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1606:16)"},"msg":"fetch failed"}
{"level":30,"time":1719386133055,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-c","res":{"statusCode":500},"responseTime":56.102778911590576,"msg":"request completed"}
{"level":30,"time":1719386398902,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-d","req":{"method":"POST","url":"/rooms","hostname":"10.21.19.136:3010","remoteAddress":"10.21.19.136","remotePort":40282},"msg":"incoming request"}
query: SELECT "worker"."id" AS "worker_id", "worker"."apiHost" AS "worker_apiHost", "worker"."for" AS "worker_for", "worker"."apiPort" AS "worker_apiPort", "worker"."pid" AS "worker_pid", "worker"."maxTransport" AS "worker_maxTransport", "worker"."transportCount" AS "worker_transportCount", "worker"."errorCount" AS "worker_errorCount" FROM "media_worker" "worker" WHERE "worker"."for" = $1 AND "worker"."transportCount" < "worker"."maxTransport" -- PARAMETERS: ["producer"]
{"level":50,"time":1719386398947,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-d","req":{"method":"POST","url":"/rooms","hostname":"10.21.19.136:3010","remoteAddress":"10.21.19.136","remotePort":40282},"res":{"statusCode":500},"err":{"type":"TypeError","message":"fetch failed: connect ECONNREFUSED 10.21.19.136:3011","stack":"TypeError: fetch failed\n at node:internal/deps/undici/undici:12500:13\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async RoomService.create (file:///home/huangqb/mediasoup-cluster/dist/services/room.js:9:24)\ncaused by: Error: connect ECONNREFUSED 10.21.19.136:3011\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1606:16)"},"msg":"fetch failed"}
{"level":30,"time":1719386398953,"pid":504647,"hostname":"huangqb-KVM","reqId":"req-d","res":{"statusCode":500},"responseTime":49.46740913391113,"msg":"request completed"}

@woody146
Copy link
Owner

check your config fetch failed: connect ECONNREFUSED 10.21.19.136:3011. Can you list ip of master server, producer slave server, consumer slave server?

@huangqingbiao8831
Copy link

huangqingbiao8831 commented Jun 26, 2024

1、master: 10.21.19.136 and .env list
DATABASE_URL = "postgresql://postgres:123456@10.21.19.136:5432/mediasoup"
DATABASE_SYNC = 1
DATABASE_LOGGING = 1

PORT = 3000

LISTEN_HOST = '10.21.19.136'

SLAVE_FOR = producer

SLAVE_MAX_TRANSPORT_PER_WORKER = 500

MEDIASOUP_LOG_LEVEL = warn
MEDIASOUP_LOG_TAGS = 'info ice dtls rtp srtp rtcp rtx bwe score simulcast svc sctp'
MEDIASOUP_NUMBER_OF_WORKERS = 2

must open port range on internet for client to connect

MEDIASOUP_RTC_MIN_PORT = 20000
MEDIASOUP_RTC_MAX_PORT = 40000
MEDIASOUP_MEDIA_CODECS = '
[
{
"kind":"audio",
"mimeType":"audio/opus",
"clockRate":48000,
"channels":2
},
{
"kind":"video",
"mimeType":"video/VP8",
"clockRate":90000,
"parameters":{
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/VP9",
"clockRate":90000,
"parameters":{
"profile-id":2,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"4d0032",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"42e01f",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
}
]'

MEDIASOUP_WEBRTC_TRANSPORT_MAX_INCOMING_BITRATE = 1500000
MEDIASOUP_WEBRTC_TRANSPORT_INITIAL_AVAILABLE_OUTGOING_BITRATE = 1000000
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
{
"ip": "10.21.19.136",
"announcedIp": null
}
]'

2、slave:producer:10.21.19.84 and .env
DATABASE_URL = "postgresql://postgres:123456@10.21.19.136:5432/mediasoup"
DATABASE_SYNC = 1
DATABASE_LOGGING = 1

PORT = 3000

LISTEN_HOST = '10.21.19.84'

SLAVE_FOR = producer

SLAVE_MAX_TRANSPORT_PER_WORKER = 5

MEDIASOUP_LOG_LEVEL = warn
MEDIASOUP_LOG_TAGS = 'info ice dtls rtp srtp rtcp rtx bwe score simulcast svc sctp'
MEDIASOUP_NUMBER_OF_WORKERS = 1

must open port range on internet for client to connect

MEDIASOUP_RTC_MIN_PORT = 20000
MEDIASOUP_RTC_MAX_PORT = 40000
MEDIASOUP_MEDIA_CODECS = '
[
{
"kind":"audio",
"mimeType":"audio/opus",
"clockRate":48000,
"channels":2
},
{
"kind":"video",
"mimeType":"video/VP8",
"clockRate":90000,
"parameters":{
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/VP9",
"clockRate":90000,
"parameters":{
"profile-id":2,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"4d0032",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"42e01f",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
}
]'

MEDIASOUP_WEBRTC_TRANSPORT_MAX_INCOMING_BITRATE = 1500000
MEDIASOUP_WEBRTC_TRANSPORT_INITIAL_AVAILABLE_OUTGOING_BITRATE = 1000000
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
{
"ip": "10.21.19.84",
"announcedIp": null
}
]'
3、slave:consumer:10.21.19.12 .env list
DATABASE_URL = "postgresql://postgres:123456@10.21.19.136:5432/mediasoup"
DATABASE_SYNC = 1
DATABASE_LOGGING = 1

PORT = 3000

LISTEN_HOST = '10.21.19.12'

SLAVE_FOR = producer

SLAVE_MAX_TRANSPORT_PER_WORKER = 5

MEDIASOUP_LOG_LEVEL = warn
MEDIASOUP_LOG_TAGS = 'info ice dtls rtp srtp rtcp rtx bwe score simulcast svc sctp'
MEDIASOUP_NUMBER_OF_WORKERS = 1

must open port range on internet for client to connect

MEDIASOUP_RTC_MIN_PORT = 20000
MEDIASOUP_RTC_MAX_PORT = 40000
MEDIASOUP_MEDIA_CODECS = '
[
{
"kind":"audio",
"mimeType":"audio/opus",
"clockRate":48000,
"channels":2
},
{
"kind":"video",
"mimeType":"video/VP8",
"clockRate":90000,
"parameters":{
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/VP9",
"clockRate":90000,
"parameters":{
"profile-id":2,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"4d0032",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
},
{
"kind":"video",
"mimeType":"video/h264",
"clockRate":90000,
"parameters":{
"packetization-mode":1,
"profile-level-id":"42e01f",
"level-asymmetry-allowed":1,
"x-google-start-bitrate":1000
}
}
]'

MEDIASOUP_WEBRTC_TRANSPORT_MAX_INCOMING_BITRATE = 1500000
MEDIASOUP_WEBRTC_TRANSPORT_INITIAL_AVAILABLE_OUTGOING_BITRATE = 1000000
MEDIASOUP_WEBRTC_TRANSPORT_LISTEN_IPS = '[
{
"ip": "10.21.19.12",
"announcedIp": null
}
]'

4、and slave next.config.js list
/** @type {import('next').NextConfig} /
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path
',
destination: 'http://10.21.19.136:3010/:path*',
},
];
},
};
5、master next.config.js list
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://10.21.19.136:3010/:path*',
},
];
},
};

@woody146
Copy link
Owner

You must set LISTEN_HOST = 10.21.19.136 in .env file for master server

@woody146
Copy link
Owner

Check at comment #1 (comment)

@woody146
Copy link
Owner

woody146 commented Jun 26, 2024

At next.config.js file should update

destination: 'http://10.21.19.136:3000/:path*',

Currently, you set 10.21.19.136:3010 but master server run at port 3000

@huangqingbiao8831
Copy link

thanks!!!!

@huangqingbiao8831
Copy link

Does it matter if the hostnames of the three hosts are the same?

@woody146
Copy link
Owner

Yes, they can be same

@huangqingbiao8831
Copy link

In the .env file, I configured the port to 3000. Why is the listening port still 3010 when starting?

{"level":30,"time":1719391499691,"pid":3024,"hostname":"huangqb-KVM1","msg":"Server listening at http://10.21.19.136:3010"}
✅ App ready: http://10.21.19.136:3010

@huangqingbiao8831
Copy link

I got answer from package.json, here...
"start:slave:producer": "cross-env PORT=3011 SLAVE_FOR=producer node dist/run_slave.js",
"start:slave:consumer": "cross-env PORT=3012 SLAVE_FOR=consumer node dist/run_slave.js",

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

3 participants