14

I want to map an API Gateway endpoint with a Socket.io server endpoint, in order to authenticate users through Cognito and, if successful, redirect to the Socket.io server and establish a socket with optional namespace and rooms.

Is that makes sense? I didn't found any example, and API Gateway has only recently enabled a WebSocket API but without support for Socket.io

Vebbie
  • 1,669
  • 2
  • 12
  • 18
Mauro Losciale
  • 165
  • 1
  • 2
  • 8
  • 2
    Did you connect successfully socket.io with the WebSocket API Gateway? I have been having lots of issues. Using native JS WebSocket implementation works fine, but not Socket.IO. – Hans Araya Jan 15 '20 at 01:37
  • 2
    Did you manage to integrate socket.io with API Gateway ?@HansAraya – Jeson Dias Mar 16 '20 at 09:50

3 Answers3

8

Your question has two parts:

First, the API Gateway using Cognito to authenticate your client;

Second, assuming you are using an EC2 running Node.JS with Socket.IO using API Gateway as an endpoint for your clients.

For the First part, you may use the following reference from AWS documentation. There are several sub-parts when you talk about AWS Cognito, for example including AIM permissions Method Execution to enable API resource endpoint HTTP method.

For the second point, enable API Gateway to establish a synchronous connection with EC2 port running Socket.io you may read some references like this one. You should configure your API Gateway:

  1. Protocol WebSocket connection
  2. Select your Route Selection expression ,e.g. \$default
  3. Map the target backend for each $connect, $disconnect and $default
    1. Use integration type AWS Service
    2. Select EC2 and fill the rest of configs.
Rafael Gorski
  • 1,483
  • 14
  • 22
4

The answer by Rafael focuses more on using the Websocket API Gateway which in my opinion is still relatively new and there is some space to improvements. Plus I don't like having lambda integrations with database access because without RDS proxy they exceed the db connections really fast, and I don't think HTTP integration adds anything to the whole thing because you're performing HTTP request in the end but it's called through the Websocket API.

One thing I agree on with Rafael is that you need to have an EC2 instance running socket.io whether it's in Node.js or python (I used python with Flask in my case).

I managed to connect to my socket.io by using the HTTP API Gateway and setting allow_upgrades=False so http protocol won't be upgraded to ws protocol, because HTTP API Gateway doesn't support ws. My HTTP API Gateway is just forwarding socket.io requests to the load balancer, and good thing about that is that you can define access control on each route defined in the HTTP API Gateway.

The socket.io on my EC2 instance is defined like this:

socketio = SocketIO(async_handlers=True, allow_upgrades=False, cors_allowed_origins='*')

And my client connects to it by simply calling the route defined in the HTTP API Gateway which has proxy integration enabled.

https://xxxxxxxxx.execute-api.us-west-2.amazonaws.com/socket.io/{proxy}

Final result - client connected to socket

socket.io connected

Josip Kolarić
  • 456
  • 1
  • 7
  • 21
  • Kindly explain with your example how it is possible. I have tried several ways. Always showing 404 for socket.io connection in the server which is running in ECS Farget. Http API gateway connecting that via ALB. – Dhiraj Aug 15 '21 at 13:51
  • 2
    Ended up doing something similar, although it may be argued that by explicitly not-upgrading / switching porotocols, you’re letting socket.io perform http long-polling, which has disadvantages compared to using true websockets. – Luc Bertin Sep 22 '21 at 10:47
2

Before websocket technology, if you wanted real-time data in your browser, you needed a wasteful polling strategy. That's why websocket technology was introduced. However, it took some time before browsers supported it. On top of that, it wasn't that good at handling reconnects.

Socket-io gave us early-access to a reliable solution by combining multiple protocols, and adding several features to improve the stability and to recover from errors. With new releases, the protocol changed, and more flags and options were added.

That evolution made socket-io what it is today, which isn't exactly an "open standard". For that reason, it will probably never be decently supported on AWS.


Some possible solutions:

  • Having said that, browsers have evolved and most of them support websockets now. So, you could consider to migrate (back) from socket-io to plain old websockets. Nevertheless, you probably want to add a "heartbeat" that sends back and forth ping/pong messages to detect disconnects (which is one of those things that socket-io has built-in).

  • However, if you like GraphQL, then you should certainly consider AWS AppSync, which amongst others supports GraphQL subscriptions to push notifications to the client. Apollo client is extremely popular and reliable.

bvdb
  • 22,839
  • 10
  • 110
  • 123