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 ?
@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:
botbuilder SDKThe problem:
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:
Path to ngrok points to your ngrok.exeBypass ngrok for local addresses is unchecked (you only want this unchecked for local docker bots since they run on localhost but still require routing)Run ngrok when the Emulator starts up is checked
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:

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.