Replies: 2 comments 1 reply
-
It should be possible. On my list of things to look into since I want to do a post on how to use Lamby with Hotwire. |
Beta Was this translation helpful? Give feedback.
1 reply
-
I think this would be super interesting. I got as far as creating the CF resources and adapter before I realized how tightly coupled Action Cable is to the WebSocket protocol. Sharing what I have so far, in case anyone's inclined to pick it up from here. ...
RailsConnectionsTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: connectionId
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
SSESpecification:
SSEEnabled: True
TableName: ...
RailsWsDomainName:
Type: AWS::ApiGatewayV2::DomainName
Properties:
DomainName: !Sub cable.${Domain}
DomainNameConfigurations:
- CertificateArn: !Ref CertificateArn
EndpointType: REGIONAL
SecurityPolicy: TLS_1_2
RailsWsApiMapping:
Type: AWS::ApiGatewayV2::ApiMapping
DependsOn: RailsWsDomainName
Properties:
ApiId: !Ref RailsWsApi
DomainName: !Sub cable.${Domain}
Stage: !Ref RailsEnv
RailsWsRecordSet:
Type: AWS::Route53::RecordSetGroup
DependsOn: RailsWsApiMapping
Properties:
HostedZoneId: !Ref HostedZoneId
RecordSets:
- Name: !Sub cable.${Domain}
Type: A
AliasTarget:
HostedZoneId: !GetAtt RailsWsDomainName.RegionalHostedZoneId
DNSName: !GetAtt RailsWsDomainName.RegionalDomainName
EvaluateTargetHealth: false
RailsWsApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: !Sub cable-${RailsEnv}
ProtocolType: WEBSOCKET
RouteSelectionExpression: "$request.body.action"
RailsWsLambdaPermission:
Type: AWS::Lambda::Permission
DependsOn:
- RailsWsApi
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref RailsLambda
Principal: apigateway.amazonaws.com
RailsWsIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref RailsWsApi
IntegrationType: AWS_PROXY
IntegrationUri:
Fn::Sub:
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RailsLambda.Arn}/invocations
PayloadFormatVersion: 1.0
RailsWsConnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref RailsWsApi
RouteKey: $connect
Target: !Join
- '/'
- - 'integrations'
- !Ref RailsWsIntegration
RailsWsDisconnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref RailsWsApi
RouteKey: $disconnect
Target: !Join
- '/'
- - 'integrations'
- !Ref RailsWsIntegration
RailsWsDefaultRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref RailsWsApi
RouteKey: $default
Target: !Join
- '/'
- - 'integrations'
- !Ref RailsWsIntegration
RailsWsDeployment:
Type: AWS::ApiGatewayV2::Deployment
DependsOn:
- RailsWsConnectRoute
- RailsWsDisconnectRoute
- RailsWsDefaultRoute
Properties:
ApiId: !Ref RailsWsApi
RailsWsStage:
Type: AWS::ApiGatewayV2::Stage
Properties:
ApiId: !Ref RailsWsApi
AutoDeploy: true
StageName: !Ref RailsEnv # frozen_string_literal: true
# https://github.com/aws-samples/simple-websockets-chat-app
module ActionCable
module SubscriptionAdapter
class APIGateway < Base
def initialize(*)
super
@api_gateway_management_api = Aws::ApiGatewayManagementApi::Client.new(
{
endpoint: @server.config.cable[:endpoint]
}
)
@dynamo_db = Aws::DynamoDB::Client.new
@table_name = @server.config.cable[:table_name]
end
def broadcast(channel, payload)
connection_ids = @dynamo_db.scan(
{
projection_expression: 'connectionId',
table_name: @table_name
}
).items.map do |item|
item['connectionId']
end
connection_ids.each do |connection_id|
@api_gateway_management_api.post_to_connection(
{
data: payload,
connection_id: connection_id
}
)
rescue Aws::ApiGatewayManagementApi::Errors::NotFoundException
@dynamo_db.delete_item(
{
key: {
connectionId: channel
},
table_name: @table_name
}
)
end
end
def subscribe(channel, callback)
@dynamo_db.put_item(
{
item: {
connectionId: channel
},
table_name: @table_name
}
)
callback.call
end
def unsubscribe(channel, callback)
@dynamo_db.delete_item(
{
key: {
connectionId: channel
},
table_name: @table_name
}
)
callback.call
end
def shutdown; end
end
end
end |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi,
Do you have any experience in getting ActionCable up and running via Lambda? I personally don't rely on this yet but I'm curious as I wanna start using the Hotwire gems and Turbo stream especially.
I would probably have to look more into AWS Api Gateway for Websocket to be successful as it definitely won't work out of the box on the HTTP api directly (at least not for my initial testing).
I'm unsure if I wanna pursue this, but just curious if there's anyone out there who's done it already.
Beta Was this translation helpful? Give feedback.
All reactions