It is currently possible to use ApiGatewayManagementApi.postToConnection to respond to an incoming WebSocket message as detailed in the
readme.
However, it would be great to have serverless-offline act in the same way as API Gateway's WebSocket APIs are able to, meaning that the body in the return value of the handler is sent back to the connected client as a WebSocket message.
Sample Code
service: my-service
plugins:
- serverless-offline
provider:
runtime: nodejs12.x
stage: dev
custom:
serverless-offline:
websocketPort: ${self:custom.websocketPort}
functions:
ws-custom:
handler: handler.wsCustom
events:
- websocket:
route: custom
routeResponseSelectionExpression: $default
'use strict'
module.exports.wsCustom = async (event) => {
const body = JSON.parse(event.body);
const payload = { message: `Hello, ${body.name}!` };
return {
statusCode: 200,
body: JSON.stringify(payload)
}
}
Expected behavior/code
If I were to deploy to AWS and run the following code in browser:
ws = new WebSocket('wss://<appid>.execute-api.ap-southeast-2.amazonaws.com/dev');
ws.onmessage = message => { console.log('message', message); };
ws.onerror = error => { console.log('error', error); };
ws.send(JSON.stringify({ action: '', name: 'kevbot-git' }));
...I would expect to see a WebSocket message come back straight away in response. However, when running locally:
ws = new WebSocket('http://localhost:3001');
ws.onmessage = message => { console.log('message', message); };
ws.onerror = error => { console.log('error', error); };
ws.send(JSON.stringify({ action: '', name: 'kevbot-git' }));
...the WebSocket connection is successful and any logs will show in the serverless console, but no response WebSocket message will be sent.
Additional context/Screenshots
Another way to repro this issue is simply to run the project's WebSocket example. When I run it, the return values do not get returned to the client in any form.
Another interesting point is that if I put code in the handler that throws an unhandled error, the WebSocket client does receive a message with the error message, ‘Internal server error’. At least there is some form of two-way communication working!
+1
This should be an easy fix. @frozenbonito what do you think?
The result need to be handled properly.
I think we'll need to do some research into the actual behavior of API Gateway.
Most helpful comment
https://github.com/dherault/serverless-offline/blob/e3ec39954547f4c040ec81b82466681dfd0aa296/src/events/websocket/WebSocketClients.js#L84-L93
The
resultneed to be handled properly.I think we'll need to do some research into the actual behavior of API Gateway.