WebSocket API gateway connection issue - aws-lambda

We are working on the ASP.Net core API application. In this application, we have a SignalR module for notification. We planned to host the application in the AWS environment. We have used the AWS lambda service to host the API, and also the WebSocket API gateway to consume the notification/SignalR part.
We are facing an issue with connecting the notification URL.
When we tried to connect the Web socket URL from Commandline using Node, it is showing "Unexpected server response 403".
When we tried to consume the URL from the frontend application, it showed the below error.
"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled. ."
We are stuck with this issue. Any help to resolve this issue would be appreciable.

Related

Laravel Pusher throwing html response in console with title "Not Found" when an even is fired using tinker

This is the error that I am getting on console while firing an event using tinker.
I am able to connect to XXXs.XXX.com:8443/laravel-websockets, where I can see the default channel and socketId is being created.
The socket has been deployed on nginx server. Server is secured with the whitelisting and blacklisting IPs/Urls. The project is running on XXXs.XXX.com:8443 port and on same the websocket is running on XXXs.XXX.com:6001 port.
For the pusher credentials, I am using: PUSHER_APP_ID=MY_ID, PUSHER_APP_KEY='MY_KEY', PUSHER_APP_SECRET=MY_SECRET,
Also the certificate has been attached, and hence no issue while connecting to socket.
Since there's no issue on local system, so I doubt there is some server/system related issue, but unable to find one.

Unable to establish a websocket connection for GraphQL subscription

I am trying to implement a GraphQL WebSocket-based #subscription on a server (using NestJS #subscription). The server is hosted on an AWS ECS and is behind an ALB.
We currently have an AWS API GW connection via VPC-link to our ALB.
I tried to build a dedicated Websocket API GW with the same VPC link we use in the HTTP API GW.
I also tried to spin up a new NLB (Network Load Balancer) over our ECS and a new REST VPC link to be used in the dedicated Websocket API GW.
The client and server are communicating over a graphql-transport-ws sub-protocol using graphql-ws library and the communication is working fine on a localhost setup.
When running the following command on our local host I am able to establish a web socket connection:
wscat -c ws://localhost:3000/graphql -s graphql-transport-ws
When running the same against the WebSocket API GW URL
wscat -c wss://*****.execute-api.*****.amazonaws.com/**** -s graphql-transport-ws
I’m getting this:
error: Server sent no subprotocol
The error indicates a problem with the sub-protocol so when removing the sub-protocol a connection is established and I am getting a prompt:
Connected (press CTRL+C to quit)
>
However, there’s no indication of reaching the server and it seems like the connection is only made with the WebSocket API GW itself.
When I circumvent the gateway and directly connect an internet-facing NLB I'm able to establish a WebSocket connection.
I am not a super Websocket expert, but I understand WebSocket connections will be terminated by the API Gateway and cannot be used as a connection pass-through. You can forward web socket events using AWS_PROXY integration to a graphQL server backend, BUT it's not a maintained direct connection - API Gateway terminates and events towards the backend integration and will not return the integration response to the WebSocket since it is event-driven and not a connection-oriented service - hence the “error: Server sent no subprotocol” you are seeing.
So to use API GW as the WebSocket layer, you would need to build out connection management functionality somewhere to manage the event-based nature of the APIGW and send out data to the APIGW connections or adjust the integration mechanism within the graphql server to utilise the #connection functionality to send responses/notifications to WebSocket consumers.
Integrating Backend Service documentation:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-routes-integrations.html
Sending responses to a connected client:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html
API GW Websockets are great for building custom solutions but take some effort since you will be configuring the setup for the events.
For a GraphQL API on AWS - I would recommend taking a look at AppSync, which is an AWS Managed GraphQL service - it handles GraphQL subscriptions via WebSockets natively and with zero additional code and its highly scalable out of the box and would simplify the GraphQL hosting burden of an ECS based solution.
I suspect there may be a lot of other reasons for the need to build out using existing GraphQL on ECS, so understand it's not always possible to pivot to something like AppSync. I feel the NLB solution you tried is okay within the existing ECS backend landscape and, as you have noted, is connection-oriented (via NLB), so will achieve the outcome you are after.

HttpClient timeout on Braintree call in Blazor

I'm deploying my .Net 6, Blazor Server site for the first time on shared hosting. It's all seems to work so far bar two things.
In the browser console (Chrome) I get an error:
Error 1
blazor.server.js:1 WebSocket connection to 'wss://www.mysite.co.uk/_blazor?id=qW5eCRVc_HbgSWt8iESawA' failed:
Information: (WebSockets transport) There was an error with the transport.
Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.
Warning: Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection. To troubleshoot this, visit https://aka.ms/blazor-server-using-fallback-long-polling.
The page seems to work & I've added all the CSP entries I can find so that's the only error left.
Error 2 is when I call Braintree to capture a payment. That's the only Braintree call & it works fine locally.
Transaction.SubmitForSettlementAsync(transactionId, amount)
gets an exception : The request was canceled due to the configured HttpClient.Timeout of 60 seconds elapsing.
I have no idea why that is & assume is blocking is call. Any help would be appreciated.
For this warning:
Warning: Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection. To troubleshoot this, visit https://aka.ms/blazor-server-using-fallback-long-polling.
see: https://learn.microsoft.com/en-us/aspnet/core/signalr/publish-to-azure-web-app?view=aspnetcore-5.0#configure-the-app-in-azure-app-service
For apps hosted without the Azure SignalR Service, enable:
ARR Affinity to route requests from a user back to the same App Service > instance. The default setting is On.
Web Sockets to allow the Web Sockets transport to function. The default setting is Off.
In the Azure portal, navigate to the web app in App Services.
Open Configuration > General settings.
Set Web sockets to On.
Verify that ARR affinity is set to On.

Monitoring websocket logs in Azure Gateway

I am aware that Azure application gateway supports websockets. However, I cant figure out from the samples and documentation how websocket access is reflected in the Access Logs.
I have been going over Azure gateway documentation for Access logs over here
https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-diagnostics#for-application-gateway-and-waf-v2-sku
There is no protocol field - which usually carry ws or wss to indicate websocket access.
Thanks for help in advance
There is no user-configurable setting to selectively enable or disable WebSocket support in Application gateway. WebSocket protocols are designed to work over traditional HTTP ports of 80 and 443. You can continue using a standard HTTP listener on port 80 or 443 to receive WebSocket traffic. WebSocket traffic is then directed to the WebSocket enabled backend server using the appropriate backend pool as specified in application gateway rules.
Here is a clear documentation explaining about Websocket workflow in Application Gateway.

Subscriptions error on Hasura GraphQL Engine deployed with Cloudfoundry on AWS

Hasura GraphQL Engine is deployed on a Cloudfoundry instance backed by AWS, it is exposed at a subdomain via an AWS ELB. The console is exposed at https://hasura.cloud.domain.com/console and the GraphQL API accepts queries at https://hasura.cloud.domain.com/v1alpha1/graphql.
But when a subscription is executed from console, an error happens with the following log on JS Console:
vendor.js:1 WebSocket connection to 'wss://hasura.cloud.domain.com/v1alpha1/graphql' failed: Error during WebSocket handshake: Unexpected response code: 200
Analyzing the websocket frames on Chrome indicates an error with (Opcode -1).
Basically, the client is unable to open a websocket connection.
Some load balancers do not support passing WebSocket handshake requests containing the Upgrade header to the CF router. For instance, the Amazon Web Services (AWS) Elastic Load Balancer (ELB) does not support this behavior. In this scenario, you must configure your load balancer to forward TCP traffic to your CF router to support WebSockets.
ref: https://docs.cloudfoundry.org/adminguide/supporting-websockets.html#config
Basically, there is some configuration required with AWS ELB and CF Router to get websockets working. This is typically done by setting up a non-standard port to forward all TCP connections to the CF Router. We have learned from our clients that this port is typically 4443.
So, to get websocket connections to work, choose the endpoint as wss://hasura.cloud.domain.com:4443/v1alpha1/graphql for websocket connections and thus subscriptions.
The console can be opened at https://hasura.cloud.domain.com:4443 as well.

Resources