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

ECONNREFUSED when sending websocket message to client when using sls offline #924

Closed
bryanvaz opened this issue Mar 17, 2020 · 7 comments
Closed

Comments

@bryanvaz
Copy link

Bug Report

Current Behavior

When trying to send a Websocket message to a local client using the standard Aws.ApiGatewayManagementApi connector in serverless-offline, the connector's TCP connection to the client is refused. However this works fine when deployed to AWS.

Tested on MacOS Catalina 10.15.3.

See https://github.com/bryanvaz/sls-websocket-demo for demo of the issue.

Not sure if this is a weird MacOS firewall issue or something else someone has encountered before. I can't seem to figure out why the initial connection is successful, but sending messages fails.

Detailed Error Message

Unable to generate socket message Error: connect ECONNREFUSED 127.0.0.1:443
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16) {
  message: 'connect ECONNREFUSED 127.0.0.1:443',
  errno: 'ECONNREFUSED',
  code: 'NetworkingError',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 443,
  region: 'us-east-1',
  hostname: '',
  retryable: true,
  time: 2020-03-17T16:37:57.040Z
}
->StackTrace:
 Error: connect ECONNREFUSED 127.0.0.1:443
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16)

Sample Code

See https://github.com/bryanvaz/sls-websocket-demo for simple demo and full description of the issue.

Expected behavior/code

The serverless-server should respond with a {"action":"PING", "value":"PONG"} message to the client.

Environment

  • serverless version: v1.66.0
  • serverless-offline version: v5.12.1 (also happens with v6.0.0-alpha.68)
  • node.js version: v12.16.1
  • OS: macOS 10.15.3
@jimishshah
Copy link

I am having same issue.

@jimishshah
Copy link

I was able to fix the issue, not sure it is with serverless but in your code https://github.com/bryanvaz/sls-websocket-demo/blob/b1c614c4db1adfedff92d399d2a6fedf407d366a/src/connector/apigateway.connector.js#L9

if you point endpoint to http://localhost:3001 which is default serverless than it should work

Bare in mind your config might be correct in aws, you only need to do that in local development

@bryanvaz
Copy link
Author

Thanks @jimishshah, but the point of the WS endpoint for serverless-offline is to test the function with a corresponding WS client that connects over WS.

@dnalborczyk I noticed you've been patching most of the WS server code in Dec. Did you ever get the WS server to send messages to the client locally?

That functionality is critical for CI-based integration and behaviour tests (Realized this is actually the most important use case last week when I spent 3 hrs digging through lamda logs.)

@ChrisTowles
Copy link

@bryanvaz You said it well but still figured i'd share my current work around when using websockets locally with sls offline that is working well for now.

  const gatewayApi = new ApiGatewayManagementApi({
    apiVersion: '2018-11-29',
    // `sls offline` has [issue](https://github.com/dherault/serverless-offline/issues/924) where it can't send
    // the message back to the websocket client (using ws://localhost:3001).
    // TODO: look for a fix to this hack
    endpoint: process.env.IS_LOCAL_SERVERLESS_MODE ? `http://localhost:3001` : `${event.requestContext.domainName}/${event.requestContext.stage}`,
  });

Here is a web client correctly receiving the message back.
image

@bryanvaz
Copy link
Author

bryanvaz commented May 5, 2020

@ChrisTowles Nice now I get it (@jimishshah now I get what you were trying to say)
Honestly I think that might be the correct way to wire up the backend. The integration tests for the websocket functionality that is sitting on a PR(GH-814) are set up the exact same way

https://github.com/computerpunc/serverless-offline/blob/websocket-integration-tests-2/__tests__/integration/websocket/main/main-handler.js#L58

@joncode
Copy link

joncode commented Nov 18, 2020

I used a slightly different proces.env.IS_OFFLINE

const endpoint = process.env.IS_OFFLINE ? 'http://localhost:3001' : ${domainName}/${stage};

@Jarrettgohh
Copy link

Take note that the localhost port should be according to what you set in the websocketPort field in the serverless.yml under serverless-offline, if you have set it. Else it defaults to 3001

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

5 participants