Connect react native mobile app to AWS websocket API - amazon-web-services

I am building a card game on mobile, with React Native and Expo. I would like to allow real-time updates during a game and I thought about using AWS Gateway's websocket API.
I created the API on AWS Gateway and the following code in React Native to connect to it:
connectToWebSocket = (onConnected) => {
const socket = new WebSocket("wss://xxxx.execute-api.us-east-1.amazonaws.com/production");
socket.addEventListener("open", (e) => {
onConnected();
});
socket.addEventListener("close", (e) => console.log("WebSocket is closed"));
socket.addEventListener("error", (e) => console.error(e));
};
Unfortunately, this gives me the error EventĀ {isTrusted: false} and does not connect.
It seems that all the available examples online are about building a web app that connects to AWS Gateway, but not for a mobile app. I've been reading tutorials for hours now and am completely stuck.
Is there any way for me to use AWS Gateway's websocket API for my project?

I figured it out! The very first thing is that my Websocket API was not deployed.
On the Routes panel, I had to go to Actions>Deploy API
The second thing is that my route Integration types were Lambdas, but I had not switched the Use Lambda Proxy integration flag on. Because of that, no event was sent to my lambda and the code was failing.
Once I had fixed both of those, I could connect without a problem :)

Related

Setting up a proxy to a Lambda using AWS API Gateway HTTP API

I want to set up a proxy to a Lambda so that all sub-endpoints get handled by the same lambda (it's a FastAPI app). I've got this working using REST APIs but I can't figure out how to do it with HTTP APIs.
I'm currently able to route specific endpoints to the lambda, and that works as expected... but I'd like to decouple the API Gateway definition from each service definition (we're following a microservices approach). From their docs it kind of sounds like you can only integrate a proxy with another HTTP endpoint, but it's not exactly clear:
To set up a route with an HTTP proxy integration that catches all requests, create an API route with a greedy path variable (for example, /parent/{proxy+}). Integrate the route with an HTTP endpoint (for example, https://petstore-demo-endpoint.execute-api.com/petstore/{proxy}) on the ANY method
Has anyone done this before? is it possible? I'd prefer to use HTTP APIs over REST APIs since they're newer, faster, and cheaper.
For the visual folk:
WORKING:
REST API:
/test/{proxy+} -> app_lambda
HTTP API:
/test/endpoint1 -> app_lambda
/test/endpoint2 -> app_lambda
NOT WORKING:
HTTP API:
/test/{proxy+} -> app_lambda
Has anyone done this before? is it possible?
Yes, I've just tested it, and there no issues with lambda integration. For my example I used:
I figured out the problem. I was trying to reuse an existing Lambda integration for my proxy. After deleting the integration and creating a new one everything worked as expected.
I'd delete the question, but in case someone runs into the same issue in the future I'm leaving it here.

loopback 4 integration with socket.io

I'm working on a project which is built on loopback 4, and now the client is asking to have notifications and messaging.
I searched a lot to find the best way to integrate socket.io with loopback 4, no luck, I found nothing
Any ideas?
LoopBack 4 does not have a first-class support for websockets yet. Raymond Feng, LoopBack's architect, created an example project to demonstrate how to route socket.io messages to Controller classes, you can find the project here:
https://github.com/raymondfeng/loopback4-example-websocket/
Quoting from the README:
This example is created to explore how to expose Websocket (socket.io)
endpoints in conjunction with LoopBack controllers.
Similarly as #loopback/rest, each websocket server is attached to an
http/https server. WebSocket controllers are mapped to different
routes (namespaces), for example:
/admins -> AdminController
/chats -> ChatController
When a client connects to the endpoint, a controller is instantiated
upon the connection event of the namespace with the socket object.
Controller methods can subscribe to one or more message types and send
messages to one or more clients.

REST API not working and redirecting with https/ssl

I have build and application with angular 5 and REST API with golang and hosted them on aws ec2 instance, I have installed ssl certificate to run the app and api on https. following is my url structure to run app and api ( api is running on 8080 port
app : https://mysite.maindomain.com
api : https://mysite.maindomain.com:8080
When I hit api after setting up the ip in host file on system it works fine but its not working with aws and redirects to https://mysite.maindomain.com:8080 when I hit any api like https://mysite.maindomain.com:8080/signup or https://mysite.maindomain.com:8080/get-user/10
Nor sure what is the issue here but everything else is working fine
I am using gin gonic as go framework and also have used RunTLS as recommended.
Not sure I fully appreciate the issue, but just in case, have you setup CORS on the API server (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
If you run a browser application served from ORIGIN1, and the browser tries to access an API on DESTINATION2, the API server must state to the browser that it is indeed authorized to reply to a browser originating from ORIGIN1.
You can for example use https://github.com/gin-contrib/cors to add CORS support to your API server.
Good luck.

Call webservice located on external server, from dialogflow webhook agent

We are testing the dialogflow platform, and would like to call a external webservice located in our servers to retrieve live data from a legacy system.
We would like to host all process logic in our server, to minimize communication issues and others, instead of using other platforms like heroku, slak, etc.
We are trying to test this sequence, but have no success:
- created a simple dialogflow agent, that asks some variables
- in the end, we activated the webhook fulfillment to call our webservice
- mapped our webservice in the fulfillment area without authentication
- in our server, started a simple node.js listener to log any https requests to allow better understanding of variables/sequence required by dialogflow
We can't detect any https calls from dialogflow: when we test our agent inside dialogflow, it seems that never calls our webservice (we see no https call logs). Are we missing any step to force dialogflow to call our webservice? Is there any example (node.js, c#, etc) that we can host in our server and use it has a starting example?

Why does grails websockets connection fail but continue to receive messages that have been subscribed to in the browser while using an AWS ELB?

Using Grails 2.5.5 with the spring-websockets plugin 1.3.1 and tomcat 8.0.37.
While using an AWS Elastic Load Balancer, the following error is shown in the Javascript console when loading the application in the browser
WebSocket connection to 'ws://...s.com/Application/stomp/059/uyqk9cdn/websocket' failed: Error during WebSocket handshake: Unexpected response code: 400
From research it has been found that the ELB doesn't support websockets and proxying within the ELB, a third party load balancer or potentially using a new Application Load Balancer (the applications are not in a VPC so this is not an easy solution) might be required.
However, after the error, the following logging is received:
Web Socket Opened...
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000
<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:admin
connected to server undefined
>>> SUBSCRIBE
id:sub-0
destination:/topic/someTopic
Messages are then received by the client fine when they are broadcast
<<< MESSAGE
destination:/topic/someTopic
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:xb71g__u-16
content-length:89
The code to initiate the websocket connection is
<r:require module="spring-websocket"/>
<r:script>
var socket = new SockJS("${createLink(uri: '/stomp')}");
var client = Stomp.over(socket);
client.connect({}, function () {
var topic = "/topic/digTicketUpdated";
console.log("Subscribing to -> " + topic);
client.subscribe(topic, function (message) {
console.log("Push Message Received From Server");
updateStatus(message.body);
});
});
</r:script>
This is taken from the grails-spring-websocket github page.
Is it possible to figure out if this is fallback that has kicked in, the websocket actually working or some other scenario. To summarise :
Is the websocket falling back to another protocol?
Is there any way to get rid of the 400 error?
Thanks to the suggestions in the comments, it was found that after the "Unexpected response code: 400" was thrown, SockJS attempted to use a long POST XHR request to emulate the web socket and it worked. This was viewable in the Network tab of Chrome Developer Tools as "xhr_streaming".
To prevent the 400 error showing in the development console, a configurable switch was implemented so web socket connections are not attempted when it is known they are not supported, such as on an AWS ELB. This was achieved by passing by removing "websocket" from the allowed protocols when instantiating SockJS :
var allowedProtocols = ['xdr-streaming', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling']
var socket = new SockJS(uri, {}, {protocols_whitelist : allowedProtocols});
var client = Stomp.over(socket);