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

Socket.io client connection through AWS Api Gateway #1370

Open
Sairyss opened this issue Jun 12, 2020 · 7 comments
Open

Socket.io client connection through AWS Api Gateway #1370

Sairyss opened this issue Jun 12, 2020 · 7 comments
Labels
question Further information is requested

Comments

@Sairyss
Copy link

Sairyss commented Jun 12, 2020

Hello. I am trying to create a connection like this: socket.io-client -> AWS Gateway API.
While trying to connect from socket.io client to an AWS Gateway API, connection can't be established.
It stucks with a status '101 switching protocols' for a few seconds, then throws 'disconnected' event and tries to reestablish connection, and the process repeats infinitely.
This doesn't happen with native WebSockets or 'ws' library though, everything connects like it should.
I think issue has something to do with how socket.io client and server sides interact with each other by exchanging certain messages which may not be generated on the AWS side of things.
So my question is: is that even possible to establish a connection like this without using proxies:
socket.io-client -> AWS Api Gateway -> socket.io(node.js),
or it always has to be Socket.io-client -> socket.io(node.js)?

Amazon AWS documention was used for configuring gateway: https://aws.amazon.com/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/
It uses standart $connect, $disconnect and $default routes, but instead of lambda its nodejs backend. The issue though is only on the client side.

@JerryLeeCS
Copy link

@Sairyss is there an update on this?

@Sairyss
Copy link
Author

Sairyss commented Sep 29, 2020

@Sairyss is there an update on this?

@JerryLeeCS I ended up using native WebSockets on a client side and $connect, $disconnect and $default routes on a backend side. I didn't find any solution to make it work with Socket.io. Seems like Socket.io connections from the frontend are not supported by AWS Gateway API, it just refuses to connect.

@darrachequesne
Copy link
Member

It seems it's possible: https://stackoverflow.com/a/56364967

@darrachequesne darrachequesne added the question Further information is requested label Oct 1, 2020
@cyberwombat
Copy link

@darrachequesne If I read that link/so post correctly he is using an EC2 server running SocketIO server? It's a little unclear. I am in the same boat - ws works fine but not socket io - no connection at all. Using default websocket server provided by aws api gateway (through serverless) .

@paul-uz
Copy link

paul-uz commented Apr 15, 2021

I'm facing the same issue. Using AWS API Gateway Websockets with Lambda Functions for the routes, and I'm seeing multiple 101 responses with super basic code:

const socket = io(
  'wss://<app_id>.execute-api.eu-west-1.amazonaws.com',
  {
    path: '/Prod',
    transports: ["websocket"],
    upgrade: false
  }
);
socket.on("connect", () => {
  console.log(socket.id);
});
socket.on("disconnect", () => {
  console.log(socket.id);
});

@lucamezzalira
Copy link

lucamezzalira commented Jun 20, 2021

I spent a bit of time checking the integration of socket.io with AWS API gateway and web socket.
out-of-the-box socket.io client doesn’t work because the protocol used by socket.io is custom and not the standard websocket one.

As specified here (bottom page):
Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds additional metadata to each packet. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a plain WebSocket server either.
Moreover, I checked the internal implementation of the socket.io server and I was able to attempt the connection but it failed, it’s not just a simple websocket wrapper.

Alternatives:

  1. using another client library or native websocket implementation. Here a basic implementation with the native websocket APIs:
const socket = new WebSocket(SOCKET_URL);

socket.addEventListener('open', function (event) {
    console.log("socket open")
    console.log(event)
});

socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

socket.addEventListener('error', function (event) {
    console.log(event)
});

socket.addEventListener('close', function (event) {
    console.log("socket close")
});

just change the SOCKET_URL with the wss URL provided by API gateway and it is going to work (as long no authentication is required, if you need authentication as well you will need a bit of more code for providing what API gateway is looking for - either API key or token).

  1. another alternative that I spotted in my researches but I didn’t try myself is creating a socket.io server on a ec2 or a container and expose via API gateway, in that way they can use socket.io because the protocol implemented between client and server will be compatible clearly.

I hope this helps :)

@tkoller-averbis
Copy link

Did anyone have sucess with the second method suggested by @lucamezzalira, i.e. tunneling the socket.io connection through the API Gateway to an EC2 instance? Possibly with an additional (sticky) Load Balancer?
So the intended setup would be Socket.IO Client -> API Gateway (with authentication?) -> Application Load Balancer -> Socket.io Server with the possibility of bidirectional communication.

Any suggestions / help is greatly appreciated!

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

No branches or pull requests

7 participants