Parse-server: Parse Live Query don't work on AWS elasticbeanstalk

Created on 29 Aug 2016  Â·  23Comments  Â·  Source: parse-community/parse-server

I have deployed NodeJs Parse server with Parse LiveQuery on AWS elasticbeanstalk but it seems like LiveQuery is not working. When i try to subscribe from my iOS client app it gives me error.

Error: Error Domain=SRWebSocketErrorDomain Code=2132 "received bad response code from server 404"

Note: When I run locally on my mac it works fine. What could be the issue with AWS ?

Most helpful comment

I had this problem recently, I am using amazon elastic beanstalk with the parse server and for the parse live query you need to configure the nginx proxy, you have to create a new directory in you root path called .ebextensions and a file nginx.config inside with yaml format, I found the default nginx conf here but you have to add two lines for the web sockets support inside location block:

proxy_set_header        Upgrade         $http_upgrade;
proxy_set_header        Connection      "upgrade";

Important

Also you need to change the protocol of you amazon instance, you need set it to TCP instead HTTP

The final file looks like this:

files:
  /etc/nginx/conf.d/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      upstream nodejs {
        server 127.0.0.1:8081;
        keepalive 256;
      }

      server {
        listen 8080;

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
        }

        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
        access_log  /var/log/nginx/access.log  main;

        location / {
            proxy_pass  http://nodejs;
            proxy_set_header   Connection "";
            proxy_http_version 1.1;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_set_header        Upgrade         $http_upgrade;
            proxy_set_header        Connection      "upgrade";
        }

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location /static {
            alias /var/app/current/static;
        }

      }

container_commands:
 removeconfig:
    command: "rm -f /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf"

All 23 comments

+1 Same issue here

This seems to be a deployment problem, and we're not explicitely supporting deployment issue on AWS, otherwise we'd spend hours debugging each specific configuration.

I encourage you to lookup the EB documentation, check if it supports correctly websockets (it may not), asking on forums like stackoverflow or gitter, reach out to AWS EB support etc...

This is definitely not the right place for such issues, as you mention, this is working fine on your local machine.

@greggmojica have you tried configuring SSL ?

@aliasad106 did you solve the problem?

@otymartin We probably need to setup SSL on elastic beanstalk and change the listener port from configuration

eb's classic load balancer doesn't support web socket. aws recently came out with application load balancer which support web sock which parse live query uses. You can be able to get Parse Live Query to work using Application Load Balancer but I have not tested it yet.

@jenlai1345 does heroku also not have web socket support ?

I had this problem recently, I am using amazon elastic beanstalk with the parse server and for the parse live query you need to configure the nginx proxy, you have to create a new directory in you root path called .ebextensions and a file nginx.config inside with yaml format, I found the default nginx conf here but you have to add two lines for the web sockets support inside location block:

proxy_set_header        Upgrade         $http_upgrade;
proxy_set_header        Connection      "upgrade";

Important

Also you need to change the protocol of you amazon instance, you need set it to TCP instead HTTP

The final file looks like this:

files:
  /etc/nginx/conf.d/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      upstream nodejs {
        server 127.0.0.1:8081;
        keepalive 256;
      }

      server {
        listen 8080;

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
        }

        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
        access_log  /var/log/nginx/access.log  main;

        location / {
            proxy_pass  http://nodejs;
            proxy_set_header   Connection "";
            proxy_http_version 1.1;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_set_header        Upgrade         $http_upgrade;
            proxy_set_header        Connection      "upgrade";
        }

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location /static {
            alias /var/app/current/static;
        }

      }

container_commands:
 removeconfig:
    command: "rm -f /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf"

@lcortess, very nice

EDIT: I fixed my problem by simply formatting the nginx.config to YAML..

@lcortess I'm getting the same error as the OP, and I've tried your solution as I'm also running Parse-Server on AWS Elastic Beanstalk with an Nginx load balancer. Could you share your Parse server folder with your keys removed (obviously)? I'm doing something wrong - Node.js is not a familiar language.

Here's a photo of my Parse-Server Project. Does this look right?

screen shot 2016-12-07 at 12 34 44 am

And my Load Balancer Listener

screen shot 2016-12-07 at 12 41 42 am

I got it working with @lcortess' config. For SSL I also had to set .ebextensions > .securelistener.config as:

option_settings:
  aws:elb:listener:443:
    SSLCertificateId: <add certificate id>
    ListenerProtocol: SSL
    InstanceProtocol: TCP
    InstancePort: 80

I'm curious to see how well this works with lots of load, ie: if the socket connection sticks or gets interrupted from the load balancer sending requests to different instances, but pardon my naiveté of ELB if that's not a concern?

Update: When accessed EC2 instance, noticed /etc/nginx/conf.d/ had duplicated nginx config files, solution was to remove dups, that solved it!

Hi, i'm having trouble configuring nginx using aws ebs, using the classic load balancer and using tcp, tried disabling the proxy server and live query works with my client. So it's definitely the nginx configuration.
I'm getting 403 from client.

Error: Optional(Error Domain=SRWebSocketErrorDomain Code=2132 "received bad response code from server 403" UserInfo={NSLocalizedDescription=received bad response code from server 403, HTTPResponseStatusCode=403})

Have the following content in 2_proxy.config in my root project:
image

files:
  /etc/nginx/conf.d/gzip.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      server {
        listen 8080;

        location /parse/ {
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-NginX-Proxy true;
          proxy_pass  http://127.0.0.1:8081/parse/;
          proxy_http_version 1.1;
          proxy_set_header        Host            $host;
          proxy_set_header        Upgrade         $http_upgrade;
          proxy_set_header        Connection      "upgrade";
        }

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
      }

My server uses the default /parse and 8081 port.
The file is a valid yaml file, verified using yamllint.com
Any idea?

I set nginx config file according to @pjchavarria and LiveQuery get received only in one client , the second client does not receive messages. I can't figure out how to solve the issue.
I've tested my android client code using back4pp api which was receiving in both devices simultaneously. They have another URL address for LiveQuery

@lcortess did you set your parse live query server port to 8081 as well? The code I pasted below is the default from the Parse Live Query server example:

var port = process.env.PORT || 1337;

Also, what's the format of the URL when creating the Live Query Client? I saw on Back4App that ws:// was used for web socket connections without SSL instead of http://.

Hello, does anyone know what could cause an undefined client id ?

info: Client disconnect: undefined
error: Can not find client undefined on disconnect
info: Client disconnect: undefined
error: Can not find client undefined on disconnect

We have an Instance running on EB. We configure the load balancer for TCP and added the following on Eb's nginx configuration file

proxy_set_header        Upgrade         $http_upgrade;
proxy_set_header        Connection      "upgrade";

@polo2244 did you finally solved the problem. We are getting same error.

Unfortunately no, i did not

@polo2244 it looks like @lcortess proposed configuration works properly.

@lcortess would you be so kind opening a PR on the docs repository for the AWS EB configuration?

@flovilmart
Before i found this thread the Live queries did not even log anything on server (and it shouldn't have since AWS ELB did not support web sockets with the old application load balancer).

After we configured our server per @lcortess 's configuration the server's logs showed and undefined client. We could have missed something during the configuration but since we tried it on 2 different ELBs (with and without a Redis Cache) we ruled that problem out.
Maybe @lcortess missed mentioning a part of his configuration ?

Regardless, a documentation for that matter is good to be available.
I am not on this project anymore, i will try to review the configuration within this week if i have time.

Hi guys, I have been seeing related erros for a long time as well . With the increasing usage of my livequery servers it seems to become a real issue now as I constantly running oom on the ec2 instances.

error: Can not find client undefined on disconnect
info: Client disconnect: undefined

I am also getting a lot of this errors on LiveQuery server logs:

2018-08-02T13:43:14.569983269Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.570948897Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.571539945Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.572265357Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.572935564Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.573600694Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.574303245Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.577229991Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.578020832Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.579277874Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"
2018-08-02T13:43:14.580776878Z error: Can not fetch userId for sessionToken "r:05344cdbb42ca352522d2dc3d1d5ad6a", error "No session found for session token"

My setup is:
[Angular.js App] --->[AWS ALB]---->[6 x Live Query Servers] --->[AWS ALB] ---> [6 x Parse Servers] ---> [Mongo Atlas]

I am not using Redis Cache Adapter with the Parse Servers seems to be a huge impact on performance comparing to inMemory, I was wondering if that is leading to those errors.

My livequery servers config:

  const redisURL = process.env.LIVEQUERY_REDIS_URL;
  const httpServer = http.createServer(app);
  httpServer.listen(port, function() {
    console.log(`Parse Live Query Server running on port ${port}`);
    console.log(`Using parse at ${process.env.PARSE_SERVER_PUBLIC_URL}`);
    if (redisURL) {
      console.log(`Using Redis at ${redisURL} .`);
    }
  });

  ParseServer.createLiveQueryServer(httpServer, {
    appId: process.env.PARSE_APP_ID,
    masterKey: process.env.PARSE_MASTER_KEY,
    serverURL: process.env.PARSE_SERVER_PUBLIC_URL,
    websocketTimeout: 10 * 1000,
    redisURL
  });

Anyone has ever faced this scenario please share your thoughts

@flavionegrao

the first issue is quite odd an client that doens't find it's connection:

error: Can not find client undefined on disconnect
info: Client disconnect: undefined

Perhaps a race condition that removed the client info from the map before disconnect
Are you able to reproduce it in a development environment?

For the session token, is the session token valid? Did the user logout in the meantime?

EDIT:

I found a code path that may disconnect the clients with this log

The clientId is set on the websocket only after the connect operation is sent, with the application keys. Therefore if the websocket quickly connects and disconnects, this will yield this log.

I'm not sure if it's an overlooked implementation detail or if there a reason for this log. Is this creating a bad experience for the users? Overall, this can probably be ignored.

Having some HTTP Upgrade issues with AWS. I grabbed the latest nginx.config file from Amazon that also includes the http_upgrade headers

I've got my load balancers set up

And in my index.js, I create the live query server:

var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
    console.log('parse-server-example running on port ' + port + '.');
});
var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer);

I have the array of live query classes in my original ParseServer object:

liveQuery: {
      classNames: ['GroupConvos', 'GroupMessages']
  },

and connecting via wss://dev.myApp.com/ returns this error over and over

ParseLiveQuery: WebSocket did disconnect with error: Optional(Starscream.WSError(type: Starscream.ErrorType.upgradeError, message: "Invalid HTTP upgrade", code: 200)).

Unclear what I'm doing wrong at this point. I had this working last week with a TCP load balancer setup but the rest of my app requires HTTP/HTTPS, and a node app should be able to support a TCP socket with the config that I have.

Any help would be appreciated. Thanks!

Edit: Was able to get sockets running beautifully with an Application Load Balancer. Thanks @flovilmart!

Are you using an application load balancer or an Elastic LB. as @jenlai1345 mentions, anything you’re doing with ELB are workarounds and ‘hacks’. Using an ALB is the way to go.

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-alb.html

Was this page helpful?
0 / 5 - 0 ratings