serverless-offline icon indicating copy to clipboard operation
serverless-offline copied to clipboard

Message handler called before async $connect handler is completed

Open Remcoman opened this issue 5 years ago • 2 comments

Bug Report

The WebSocket server should wait for async $connect handler to be completed before accepting messages. (This is how the AWS gateway api works)

Current Behavior

The server does not wait for the $connect handler to be completed. For example if i implement the following logic:

  1. Browser client connects to websocket
  2. $connect handler is called and "connectionId" is assigned to user in database (this is async)
  3. Browser client sends ws message to server
  4. "x" handler is called

The result is that "x" handler is executed before the $connect handler has completed. Which is unexpected.

Sample Code

  • file: serverless.yml
service: my-service

plugins:
  - serverless-offline

provider:
  runtime: nodejs12.x
  stage: dev
  websocketsApiRouteSelectionExpression : $request.body.action

functions:
  connect:
    events:
      - websocket:
          route: $connect
    handler: handler.connect
 getGameState:
    events:
      - websocket:
          route: GET_GAME_STATE
     handler: handler.getGameState
  • file: handler.js
'use strict'

exports.connect = async function connect() {
  return new Promise((resolve) => {
      setTimeout(() => {
          console.log('connected');
          resolve({
               body: 'Ok',
               statusCode: 200,
          });
     }, 1000);
  });
}

exports.getGameState = function () {
   console.log('get game state');
}

Expected behavior/code

"connected" should log before "get game state"

Environment

  • serverless version: [e.g. v2.4.0]
  • serverless-offline version: [e.g. v6.5.0]
  • node.js version: [e.g. v13.2.0]
  • OS: [e.g. macOS 10.13.4]

Possible Solution

I propose to change the logic so that the $connect handler is called during the WebSocket handshake. Only when the handshake has successfully completed we should allow subsequent messages to be processed.

Remcoman avatar Oct 05 '20 10:10 Remcoman

@Remcoman Hi, I'm having the exact same issue. How did you workaround this? I thought about sending a message when $connect finishes handling the business logic (like 'CONNECTION_ESTABLISHED') but apparently you are not able to send messages to a client during $connect.

peledni avatar Jan 29 '22 17:01 peledni

@Remcoman @peledni I ran into something similar, and I believe it was fixed in v8.5.0. Give it a shot!

aardvarkk avatar Mar 02 '22 19:03 aardvarkk