@@ -43,147 +43,157 @@ npn install --save laravel-echo-api-gateway
4343
4444### Platform-specific instructions
4545
46- #### A. When using Bref
47-
48- Next, when using Bref, we have to add some elements to our ` serverless.yml ` file. If using Vapor, these resources have
49- to be created by hand using the AWS CLI or console.
50-
51- Add a new function that will handle websocket events (messages etc):
52-
53- ``` yaml
54- functions :
55- # Add this function
56- websocket :
57- handler : handlers/websocket.php
58- layers :
59- - ${bref:layer.php-80}
60- events :
61- - websocket : $disconnect
62- - websocket : $default
63- ` ` `
64-
65- Add a resource to create and configure our DynamoDB table, where connections will be stored in:
66-
67- ` ` ` yaml
68- resources :
69- Resources :
70- # Add this resource
71- ConnectionsTable :
72- Type : AWS::DynamoDB::Table
73- Properties :
74- TableName : connections
75- AttributeDefinitions :
76- - AttributeName : connectionId
77- AttributeType : S
78- - AttributeName : channel
79- AttributeType : S
80- KeySchema :
81- - AttributeName : connectionId
82- KeyType : HASH
83- - AttributeName : channel
84- KeyType : RANGE
85- GlobalSecondaryIndexes :
86- - IndexName : lookup-by-channel
87- KeySchema :
88- - AttributeName : channel
89- KeyType : HASH
90- Projection :
91- ProjectionType : ALL
92- - IndexName : lookup-by-connection
93- KeySchema :
94- - AttributeName : connectionId
95- KeyType : HASH
96- Projection :
97- ProjectionType : ALL
98- BillingMode : PAY_PER_REQUEST
99- ` ` `
100-
101- Add the following ` iamRoleStatement` to enable our Lambda function to access the table:
102-
103- ` ` ` yaml
104- provider:
105- name: aws
106-
107- iamRoleStatements:
108- # Add this iamRoleStatement
109- - Effect: Allow
110- Action: [ dynamodb:Query, dynamodb:GetItem, dynamodb:PutItem, dynamodb:UpdateItem, dynamodb:DeleteItem, dynamodb:BatchWriteItem ]
111- Resource:
112- - !GetAtt ConnectionsTable.Arn
113- - !Join [ '', [ !GetAtt ConnectionsTable.Arn, '/index/*' ] ]
114- ` ` `
115-
116- Add an environment variable to autogenerate our websocket URL :
117-
118- ` ` ` yaml
119- provider:
120- name: aws
121-
122- environment:
123- # Add these variables
124- BROADCAST_DRIVER: laravel-echo-api-gateway
125- LARAVEL_ECHO_API_GATEWAY_DYNAMODB_TABLE: !Ref ConnectionsTable
126- LARAVEL_ECHO_API_GATEWAY_API_ID: !Ref WebsocketsApi
127- LARAVEL_ECHO_API_GATEWAY_API_STAGE: "${self:provider.stage}"
128- ` ` `
129-
130- Next, create the PHP handler file in `handlers/websocket.php`
131-
132- ` ` ` php
133- <?php
134-
135- use Georgeboot\L aravelEchoApiGateway\H andler;
136- use Illuminate\F oundation\A pplication;
137-
138- require __DIR__ . '/../vendor/autoload.php';
139-
140- /** @var Application $app */
141- $app = require __DIR__ . '/../bootstrap/app.php';
142-
143- $kernel = $app->make(Illuminate\C ontracts\C onsole\K ernel::class);
144- $kernel->bootstrap();
145-
146- return $app->make(Handler::class);
147- ` ` `
148-
149- Now, deploy your app by running `serverless deploy` or similar. Write down the websocket url the output gives you.
150-
151- # ### B. When using Vapor
152-
153- When using Vapor, you will have to create these required resources by hand using the AWS CLI or Console :
154-
155- # #### B1. DynamoDB table for connections
156-
157- Create a DynamoDB table for the connections. Use `connectionId` (string) as a HASH key, and `channel` (string) as a SORT
158- key. Set the capacity setting to whatever you like (probably on-demand).
159-
160- Create 2 indexes :
161-
162- 1. Name : ` lookup-by-connection` , key: `connectionId`, no sort key, projected: ALL
163- 2. Name : ` lookup-by-channel` , key: `channel`, no sort key, projected: ALL
164-
165- # #### B2. API Gateway
166-
167- Create a new Websocket API. Enter a name and leave the route selection expression to what it is. Add a `$disconnect`
168- and `$default`. Set both integrations to `Lambda` and select your CLI lambda from the list. Set the name of the stage to
169- what you desire and create the API. Once created, write down the ID, as we'll need it later.
170-
171- # #### B3. IAM Permissions
172-
173- In IAM, go to roles and open `laravel-vapor-role`. Open the inline policy and edit it. On the JSON tab,
174- add `"execute-api:*"` to the list of actions.
175-
176- Then, login to [Laravel Vapor](https://vapor.laravel.com/app), go to team settings, AWS Accounts, click on Role next to
177- the correct account and deselect Receive Updates.
178-
179- Edit your `.env` :
180-
181- ` ` ` dotenv
182- BROADCAST_DRIVER=laravel-echo-api-gateway
183- LARAVEL_ECHO_API_GATEWAY_DYNAMODB_TABLE=the-table-name-you-entered-when-creating-it
184- LARAVEL_ECHO_API_GATEWAY_API_ID=your-websocket-api-id
185- LARAVEL_ECHO_API_GATEWAY_API_STAGE=your-api-stage-name
186- ` ` `
46+ <details >
47+ <summary >Expand Bref-specific instructions</summary >
48+
49+ #### A. When using Bref
50+
51+ Next, when using Bref, we have to add some elements to our `serverless.yml` file. If using Vapor, these resources have
52+ to be created by hand using the AWS CLI or console.
53+
54+ Add a new function that will handle websocket events (messages etc):
55+
56+ ```yaml
57+ functions:
58+ # Add this function
59+ websocket:
60+ handler: handlers/websocket.php
61+ layers:
62+ - ${bref:layer.php-80}
63+ events:
64+ - websocket: $disconnect
65+ - websocket: $default
66+ ```
67+
68+ Add a resource to create and configure our DynamoDB table, where connections will be stored in:
69+
70+ ```yaml
71+ resources:
72+ Resources:
73+ # Add this resource
74+ ConnectionsTable:
75+ Type: AWS::DynamoDB::Table
76+ Properties:
77+ TableName: connections
78+ AttributeDefinitions:
79+ - AttributeName: connectionId
80+ AttributeType: S
81+ - AttributeName: channel
82+ AttributeType: S
83+ KeySchema:
84+ - AttributeName: connectionId
85+ KeyType: HASH
86+ - AttributeName: channel
87+ KeyType: RANGE
88+ GlobalSecondaryIndexes:
89+ - IndexName: lookup-by-channel
90+ KeySchema:
91+ - AttributeName: channel
92+ KeyType: HASH
93+ Projection:
94+ ProjectionType: ALL
95+ - IndexName: lookup-by-connection
96+ KeySchema:
97+ - AttributeName: connectionId
98+ KeyType: HASH
99+ Projection:
100+ ProjectionType: ALL
101+ BillingMode: PAY_PER_REQUEST
102+ ```
103+
104+ Add the following `iamRoleStatement` to enable our Lambda function to access the table:
105+
106+ ```yaml
107+ provider:
108+ name: aws
109+
110+ iamRoleStatements:
111+ # Add this iamRoleStatement
112+ - Effect: Allow
113+ Action: [ dynamodb:Query, dynamodb:GetItem, dynamodb:PutItem, dynamodb:UpdateItem, dynamodb:DeleteItem, dynamodb:BatchWriteItem ]
114+ Resource:
115+ - !GetAtt ConnectionsTable.Arn
116+ - !Join [ '', [ !GetAtt ConnectionsTable.Arn, '/index/*' ] ]
117+ ```
118+
119+ Add an environment variable to autogenerate our websocket URL:
120+
121+ ```yaml
122+ provider:
123+ name: aws
124+
125+ environment:
126+ # Add these variables
127+ BROADCAST_DRIVER: laravel-echo-api-gateway
128+ LARAVEL_ECHO_API_GATEWAY_DYNAMODB_TABLE: !Ref ConnectionsTable
129+ LARAVEL_ECHO_API_GATEWAY_API_ID: !Ref WebsocketsApi
130+ LARAVEL_ECHO_API_GATEWAY_API_STAGE: "${self:provider.stage}"
131+ ```
132+
133+ Next, create the PHP handler file in `handlers/websocket.php`
134+
135+ ```php
136+ <?php
137+
138+ use Georgeboot\LaravelEchoApiGateway\Handler;
139+ use Illuminate\Foundation\Application;
140+
141+ require __DIR__ . '/../vendor/autoload.php';
142+
143+ /** @var Application $app */
144+ $app = require __DIR__ . '/../bootstrap/app.php';
145+
146+ $kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
147+ $kernel->bootstrap();
148+
149+ return $app->make(Handler::class);
150+ ```
151+
152+ Now, deploy your app by running `serverless deploy` or similar. Write down the websocket url the output gives you.
153+
154+ </details >
155+
156+ <details >
157+ <summary >Expand Vapor-specific instructions</summary >
158+
159+ #### B. When using Vapor
160+
161+ When using Vapor, you will have to create these required resources by hand using the AWS CLI or Console:
162+
163+ ##### B1. DynamoDB table for connections
164+
165+ Create a DynamoDB table for the connections. Use `connectionId` (string) as a HASH key, and `channel` (string) as a SORT
166+ key. Set the capacity setting to whatever you like (probably on-demand).
167+
168+ Create 2 indexes:
169+
170+ 1. Name: `lookup-by-connection`, key: `connectionId`, no sort key, projected: ALL
171+ 2. Name: `lookup-by-channel`, key: `channel`, no sort key, projected: ALL
172+
173+ ##### B2. API Gateway
174+
175+ Create a new Websocket API. Enter a name and leave the route selection expression to what it is. Add a `$disconnect`
176+ and `$default`. Set both integrations to `Lambda` and select your CLI lambda from the list. Set the name of the stage to
177+ what you desire and create the API. Once created, write down the ID, as we'll need it later.
178+
179+ ##### B3. IAM Permissions
180+
181+ In IAM, go to roles and open `laravel-vapor-role`. Open the inline policy and edit it. On the JSON tab,
182+ add `"execute-api:*"` to the list of actions.
183+
184+ Then, login to [Laravel Vapor](https://vapor.laravel.com/app), go to team settings, AWS Accounts, click on Role next to
185+ the correct account and deselect Receive Updates.
186+
187+ Edit your `.env`:
188+
189+ ```dotenv
190+ BROADCAST_DRIVER=laravel-echo-api-gateway
191+ LARAVEL_ECHO_API_GATEWAY_DYNAMODB_TABLE=the-table-name-you-entered-when-creating-it
192+ LARAVEL_ECHO_API_GATEWAY_API_ID=your-websocket-api-id
193+ LARAVEL_ECHO_API_GATEWAY_API_STAGE=your-api-stage-name
194+ ```
195+
196+ </details >
187197
188198### Generate front-end code
189199
0 commit comments