Botframework-sdk: SDK Node.js & Docker: ECONNREFUSED 127.0.0.1:51024

Created on 9 Sep 2019  ·  16Comments  ·  Source: microsoft/botframework-sdk

Hello !

I'm trying to push a bot built with Node.js Botframework SDK v4.
The bot is starting up and when I'm sending a first message with Bot Framework SDK, I get this error: ECONNREFUSED 127.0.0.1:51024

The stack:

Error: connect ECONNREFUSED 127.0.0.1:51024
    at new RestError (/usr/src/node_modules/@azure/ms-rest-js/dist/msRest.node.js:1397:28)
    at AxiosHttpClient.<anonymous> (/usr/src/node_modules/@azure/ms-rest-js/dist/msRest.node.js:1550:35)
    at step (/usr/src/node_modules/tslib/tslib.js:136:27)
    at Object.throw (/usr/src/node_modules/tslib/tslib.js:117:57)
    at rejected (/usr/src/node_modules/tslib/tslib.js:108:69)
    at process._tickCallback (internal/process/next_tick.js:68:7)
BotFrameworkAdapter.processActivity(): 500 ERROR - Error: connect ECONNREFUSED 127.0.0.1:51024
(node:44) UnhandledPromiseRejectionWarning: Error: Error: connect ECONNREFUSED 127.0.0.1:51024
    at BotFrameworkAdapter.processActivity (/usr/src/node_modules/botbuilder/lib/botFrameworkAdapter.js:511:19)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:44) 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(). (rejection id: 10)

What is this 51024 port ?

Bot Services customer-replied-to customer-reported

All 16 comments

@simon-tannai Looks like your bot is trying to start listening at 127.0.0.1:51024 but the port is probably in use by something else.

Can you provide steps to reproduce? That's not the standard Bot Framework port number (:3978).

As you're running this in docker, you may need to expose the port when starting the container with something like:

docker run -d -p 51024:51204

@simon-tannai, thanks for reporting. Are you seeing this in the Emulator? Could you hit the bot endpoint directly via postman? We'll also get someone from Support team to help.

@mdrichardson I'm using Dockerfile and Docker Compose. My bot is listening on port 3978.

Dockerfile:

# Build step
FROM node:10.16 AS cm-botframework-prebuild

# Create future workdir
RUN mkdir -p /usr/src

# Define workdir
WORKDIR /usr/src

# Copy sources files
COPY ./dialogs /usr/src/dialogs
COPY ./.env /usr/src/.env
COPY ./bot.js /usr/src/bot.js
COPY ./index.js /usr/src/index.js
COPY ./package.json /usr/src/package.json
COPY ./package-lock.json /usr/src/package-lock.json

# Install dependencies
RUN npm i

###################################################################

# Final step
FROM node:10.16

# Get files from build step
COPY --from=cm-botframework-prebuild /usr/src /usr/src

# Define bot as workdir
WORKDIR /usr/src

# Expose bot port
EXPOSE 3978

Docker compose:

cm-botframework-bot:
    build:
      context: ./../bot-server
      dockerfile: ./Dockerfile
    container_name: cm-botframework-bot
    command: npm run watch
    volumes:
      - ./../bot-server/dialogs:/usr/src/dialogs
      - ./../bot-server/.env:/usr/src/.env
      - ./../bot-server/bot.js:/usr/src/bot.js
      - ./../bot-server/index.js:/usr/src/index.js
      - ./../bot-server/package.json:/usr/src/package.json
      - ./../bot-server/package-lock.json:/usr/src/package-lock.json
    ports:
      - 3978:3978
    networks:
      cm-botframework:
        aliases:
          - cm-botframework-bot

From Postman, a simple POST request on http://127.0.0.1:3978/api/messages is working.

But through Bot Framework Emulator, it still not working. The port changed for http://localhost:50073. It seems the bot tried to reply to the Emulator on localhost. His request was not go outside of Docker's virtual network.

I tested with Ngrok tunneling and it's working fine.

I don't know if it's possible to "force" a localhost request from Docker's container to hit on host machine :S

I think I understand. Are you saying that your requests are going like this:

[LM] = Local Machine
[D] = Docker

Emulator[LM] -> Bot[D] -XXX Request Not working

or

Ngrok'd-Emulator[LM] -> Bot[D] -> Ngrok'd-Emulator[LM]

When instead, you want this:

Emulator[LM] -> Bot[D] -> Emulator[LM]

I'm having a little trouble understanding what's happening vs. what's expected.

If I have this right, I don't believe you have an option other than to use ngrok. What's really happening is that messages get routed through Directline (a cloud service) and the urls for both Emulator and the Bot are localhost, but the Bot's is really localhost to the container.

You may be able to get around this with offline-directline, but I haven't tested it myself.

Let me know if we're on the same page and I can test implementing this.

@simon-tannai Are you still experiencing this issue? It needs to stay active to stay open.

Closing due to lack of activity

@mdrichardson Sorry for the delay :S

I had tested offline directline but I got an error with it. I had opened an issue bot I didn't got any reply.

@simon-tannai As posted above, can you explain what's happening vs. what you expect?

@mdrichardson the process which you described above is exactly what's happen and what I expect. I would like to find a solution to not be forced to use Direct Line.
Offline-directline package seems to be a good solution but it seems to not be maintain.

I've ended up here with the same issue. If anyone finds these clues revealing....

Context:

  • I'm building a bot with the botbuilder SDK
  • I'm used to Bot Framework emulator for testing the bot locally
  • Everything works fine till this point ✅

The problem:

  • I've decided to dockerize the service (*)
  • Running the container which is exposing the server everything seems fine until:
  • Tried to open the bot in the emulator 🔴

The error

(node:21) UnhandledPromiseRejectionWarning: Error: BotFrameworkAdapter.processActivity(): 500 ERROR
 Error: connect ECONNREFUSED 127.0.0.1:56868
    at new RestError (/usr/src/app/node_modules/@azure/ms-rest-js/dist/msRest.node.js:1403:28)
    at AxiosHttpClient.<anonymous> (/usr/src/app/node_modules/@azure/ms-rest-js/dist/msRest.node.js:2194:35)
    at step (/usr/src/app/node_modules/tslib/tslib.js:141:27)
    at Object.throw (/usr/src/app/node_modules/tslib/tslib.js:122:57)
    at rejected (/usr/src/app/node_modules/tslib/tslib.js:113:69)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at BotFrameworkAdapter.<anonymous> (/usr/src/app/node_modules/botbuilder/lib/botFrameworkAdapter.js:769:27)
    at Generator.throw (<anonymous>)
    at rejected (/usr/src/app/node_modules/botbuilder/lib/botFrameworkAdapter.js:12:65)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

Some clues

So, first thing comes to my mind: _who is 56868_ (in case of @simon-tannai, the problematic port was 51024 instead... the number will change for sure)

 $» lsof -i tcp:56868

COMMAND     PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Bot\x20Fr 13197 martero   56u  IPv6 0x1b17a78f9dc82995      0t0  TCP *:56868 (LISTEN)
Bot\x20Fr 13197 martero   67u  IPv6 0x1b17a78fa77edcd5      0t0  TCP localhost:56877->localhost:56868 (CLOSE_WAIT)

Ok, so that's Bot Framework emulator listening on that port. My running container can't reach localhost:56868 (the emulator)

(*) Dockerize the service

Just for reference, this is my dockerfile:

FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . ./
EXPOSE 3978
CMD [ "npm", "start" ]

which I run as: docker run -p 3978:3978 <name:tag>

@manutero Are you running ngrok? Ngrok (or similar tunneling service) is required for having Emulator communicate with a Dockerized bot running locally.

Yep:

ngrok http -host-header=rewrite 3978
[...]
Forwarding                    https://0d947dcab353.ngrok.io -> http://localhost:3978

The container is routing port 3978:

$» docker run -p 3978:3978 <my-service:my-version>

(I can check this setup since the server is returning a simple string at root path)

 $» curl localhost:3978
"my-service@my-version"

Now, when I open the emulator connecting to http://0d947dcab353.ngrok.io/api/messages

(node:20) UnhandledPromiseRejectionWarning: Error: BotFrameworkAdapter.processActivity(): 500 ERROR
 Error: connect ECONNREFUSED 127.0.0.1:50261
    at new RestError (/usr/src/app/node_modules/@azure/ms-rest-js/dist/msRest.node.js:1403:28)
    at AxiosHttpClient.<anonymous> (/usr/src/app/node_modules/@azure/ms-rest-js/dist/msRest.node.js:2194:35)
    at step (/usr/src/app/node_modules/tslib/tslib.js:141:27)
    at Object.throw (/usr/src/app/node_modules/tslib/tslib.js:122:57)
    at rejected (/usr/src/app/node_modules/tslib/tslib.js:113:69)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at BotFrameworkAdapter.<anonymous> (/usr/src/app/node_modules/botbuilder/lib/botFrameworkAdapter.js:769:27)
    at Generator.throw (<anonymous>)
    at rejected (/usr/src/app/node_modules/botbuilder/lib/botFrameworkAdapter.js:12:65)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
[...]

Now, are you saying to run ngrok from the running container?

@manutero It's been awhile since I dockerized a bot. I'll attempt to repro today and see what I can figure out.

@manutero With the recent versions of Emulator, you shouldn't need to run ngrok manually.

First, please close your current running instance of ngrok.exe.

Please ensure that you have the following Emulator settings:

  1. Path to ngrok points to your ngrok.exe
  2. Bypass ngrok for local addresses is unchecked (you only want this unchecked for local docker bots since they run on localhost but still require routing)
  3. Run ngrok when the Emulator starts up is checked

image

Click Save, then when you Open Bot, use the http://localhost:3978/api/messages url and NOT the ngrok URL.

Then, make sure you see this in the log panel:

image

All of this is necessary for locally-running dockerized bots because of how docker intercepts and routes exposed ports.

Thnks @mdrichardson !!! works like a charm 👍

@manutero AWESOME! Just FYI, in the future, open up a new issue and then just reference this one. You're _much_ more likely to get a response to an open issue vs. a new comment on a closed one.

Was this page helpful?
0 / 5 - 0 ratings