asnyp
asnyp

Reputation: 11

Socket.io not working when updating from Angular v16 to Angular v17

I am maintaining a website built using Angular v16 and I am updating it to Angular v17. I've followed the update guide from the official angular website (link) and I use Angular Material (relevant for the update guide). The backend is built in Flask (python) and uses flask-socketio, python-socketio and python-engineio to communicate with the frontend which uses ngx-socket-io.

These are the versions I use of each :

ngx-cosket-io flask-socketio python-socketio python-engineio Angular version
4.6.1 5.3.2 5.7.2 4.3.4 17.3.12

For development and testing I build the website in a docker container. When starting the container and going to the website, there is a major part of the website that doesn't load (it all worked normally before the update of the packages). On the browser's console I get the following repeated log messages:

[WARNING] FallbackRequestedError: FallbackRequested
[ERROR] POST http://localhost:8080/socket.io/?EIO=4&transport=polling&t=PEC6Jwp&sid=4wpDrYkU6lD0wH_XAAIc 500 (Internal Server Error)
[ERROR] GET http://localhost:8080/socket.io/?EIO=4&transport=polling&t=PEC6Jwp&sid=4wpDrYkU6lD0wH_XAAIc 400 (BAD REQUEST)
[ERROR] POST http://localhost:8080/socket.io/?EIO=4&transport=polling&t=PEC6Jwp&sid=4wpDrYkU6lD0wH_XAAIc 400 (BAD REQUEST)

Here are the python packages modules I use for the backend :

astroid==2.14.2
attrs==22.2.0
Authlib==1.1.0
bidict==0.22.0
certifi==2022.12.07
cffi==1.15.1
charset-normalizer==2.1.1
click==8.1.3
colorama==0.4.6
coverage==7.2.1
cryptography==38.0.4
dill==0.3.6
dnspython==2.2.1
opensearch-py==2.5.0
eventlet==0.33.2
exceptiongroup==1.1.0
Flask==2.2.2
Flask-Cors==3.0.10
Flask-SocketIO==5.3.2
greenlet==2.0.1
idna==3.4
importlib-metadata==6.0.0
iniconfig==2.0.0
isort==5.12.0
itsdangerous==2.1.2
Jinja2==3.1.2
lazy-object-proxy==1.9.0
MarkupSafe==2.1.1
mccabe==0.7.0
packaging==23.0
platformdirs==3.0.0
pluggy==1.0.0
pycparser==2.21
PyJWT==2.6.0
pylint==2.16.2
pytest==7.2.1
python-engineio==4.3.4
python-socketio==5.7.2
PyYAML==6.0
requests==2.28.1
six==1.16.0
tomli==2.0.1
tomlkit==0.11.6
typing_extensions==4.5.0
urllib3==1.26.18
Werkzeug==2.2.2
sentry_sdk==1.17.0
sentry-sdk[flask]==1.17.0
wrapt==1.15.0
zipp==3.15.0

As well as the modules I use in the frontend :

{
  "name": "service-name",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build:master": "ng build --configuration=production",
    "build:qa": "ng build --configuration=qa",
    "build:dev": "ng build --configuration=dev",
    "build:local": "ng build --configuration=development",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "source-map-explorer": "source-map-explorer dist/service-name/**/*.js"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^17.3.12",
    "@angular/cdk": "^17.3.10",
    "@angular/common": "^17.3.12",
    "@angular/compiler": "^17.3.12",
    "@angular/core": "^17.3.12",
    "@angular/forms": "^17.3.12",
    "@angular/material": "^17.3.10",
    "@angular/platform-browser": "^17.3.12",
    "@angular/platform-browser-dynamic": "^17.3.12",
    "@angular/router": "^17.3.12",
    "angular-calendar": "0.31.0",
    "date-fns": "^2.30.0",
    "file-saver-es": "^2.0.5",
    "ngx-socket-io": "4.6.1",
    "rxjs": "~7.5.0",
    "source-map-explorer": "^2.5.3",
    "tslib": "^2.6.2",
    "zone.js": "~0.14.10"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.3.10",
    "@angular/cli": "^17.3.10",
    "@angular/compiler-cli": "^17.3.12",
    "@types/file-saver": "^2.0.7",
    "@types/file-saver-es": "^2.0.3",
    "@types/jasmine": "~3.10.18",
    "@types/node": "^12.11.1",
    "jasmine-core": "~4.0.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.1.0",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "prettier": "2.8.7",
    "typescript": "5.4.5"
  }
}

I tried to regenerate the package-lock.json file and it created a much smaller one with which the website still didn't work. (I am not attaching a copy of the file as it is over 15000 lines long…)

I also have this stack trace from the error 500 found in the logs from the docker container. I've filtered it by the socket id that caused the issue and enabled more logging options from socketio and engineio.

4wpDrYkU6lD0wH_XAAIc: Sending packet OPEN data {'sid': '4wpDrYkU6lD0wH_XAAIc', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Sending packet OPEN data {'sid': '4wpDrYkU6lD0wH_XAAIc', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
172.18.0.1 - - [03/Dec/2024 11:36:49] "GET /socket.io/?EIO=4&transport=polling&t=PEC60OL HTTP/1.1" 200 297 0.004877
|
|
|
4wpDrYkU6lD0wH_XAAIc: Received packet MESSAGE data 0/jobs,
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Received packet MESSAGE data 0/jobs,
emitting event "connect" to T8cEJsgyoppDDBtLAAId [/jobs]
INFO:socketio.server:emitting event "connect" to T8cEJsgyoppDDBtLAAId [/jobs]
4wpDrYkU6lD0wH_XAAIc: Sending packet MESSAGE data 2/jobs,["connect","null"]
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Sending packet MESSAGE data 2/jobs,["connect","null"]
4wpDrYkU6lD0wH_XAAIc: Sending packet MESSAGE data 0/jobs,{"sid":"T8cEJsgyoppDDBtLAAId"}
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Sending packet MESSAGE data 0/jobs,{"sid":"T8cEJsgyoppDDBtLAAId"}
172.18.0.1 - - [03/Dec/2024 11:37:10] "POST /socket.io/?EIO=4&transport=polling&t=PEC61aW&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 200 238 0.007720
172.18.0.1 - - [03/Dec/2024 11:37:10] "GET /socket.io/?EIO=4&transport=polling&t=PEC61aY&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 200 265 0.002316
|
|
|
4wpDrYkU6lD0wH_XAAIc: Sending packet PING data None
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Sending packet PING data None
|
|
|
172.18.0.1 - - [03/Dec/2024 11:37:30] "GET /socket.io/?EIO=4&transport=polling&t=PEC66h6&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 200 200 0.001024
|
|
|
4wpDrYkU6lD0wH_XAAIc: Received packet PONG data 
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Received packet PONG data 
172.18.0.1 - - [03/Dec/2024 11:37:39] "POST /socket.io/?EIO=4&transport=polling&t=PEC6BXu&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 200 238 0.003396
|
|
|
4wpDrYkU6lD0wH_XAAIc: Sending packet PING data None
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Sending packet PING data None
172.18.0.1 - - [03/Dec/2024 11:38:04] "GET /socket.io/?EIO=4&transport=polling&t=PEC6BXv&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 200 200 24.956527
|
|
|
4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
emitting event "disconnect" to T8cEJsgyoppDDBtLAAId [/jobs]
INFO:socketio.server:emitting event "disconnect" to T8cEJsgyoppDDBtLAAId [/jobs]
4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
INFO:engineio.server:4wpDrYkU6lD0wH_XAAIc: Client is gone, closing socket
|
|
|
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/eventlet/wsgi.py", line 569, in handle_one_response
    result = self.application(self.environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/sentry_sdk/integrations/flask.py", line 88, in sentry_patched_wsgi_app
    return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(
  File "/usr/local/lib/python3.9/site-packages/sentry_sdk/integrations/wsgi.py", line 143, in __call__
    reraise(*_capture_exception(hub))
  File "/usr/local/lib/python3.9/site-packages/sentry_sdk/_compat.py", line 60, in reraise
    raise value
  File "/usr/local/lib/python3.9/site-packages/sentry_sdk/integrations/wsgi.py", line 136, in __call__
    rv = self.app(
  File "/usr/local/lib/python3.9/site-packages/sentry_sdk/integrations/flask.py", line 88, in <lambda>
    return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2548, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/flask_socketio/__init__.py", line 43, in __call__
    return super(_SocketIOMiddleware, self).__call__(environ,
  File "/usr/local/lib/python3.9/site-packages/engineio/middleware.py", line 63, in __call__
    return self.engineio_app.handle_request(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/socketio/server.py", line 605, in handle_request
    return self.eio.handle_request(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/engineio/server.py", line 429, in handle_request
    socket = self._get_socket(sid)
  File "/usr/local/lib/python3.9/site-packages/engineio/server.py", line 638, in _get_socket
    raise KeyError('Session is disconnected')
KeyError: 'Session is disconnected'

172.18.0.1 - - [03/Dec/2024 11:38:27] "POST /socket.io/?EIO=4&transport=polling&t=PEC6Jwp&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 500 1995 0.013578
(8) accepted ('172.18.0.1', 56808)
Invalid session 4wpDrYkU6lD0wH_XAAIc (further occurrences of this error will be logged with level INFO)
ERROR:engineio.server:Invalid session 4wpDrYkU6lD0wH_XAAIc (further occurrences of this error will be logged with level INFO)
172.18.0.1 - - [03/Dec/2024 11:38:27] "GET /socket.io/?EIO=4&transport=polling&t=PEC6Jwp.0&sid=4wpDrYkU6lD0wH_XAAIc HTTP/1.1" 400 211 0.001751

Upvotes: 1

Views: 141

Answers (1)

asnyp
asnyp

Reputation: 11

The problem originated from the way the sockets are configured in the python files, as the different namespaces used for the project were not specified on each socket.on(...) or emit(...) method.

Python files after fix:

# Example from main.py file
socketio.on_event('getter', jobs.getter, namespace='/jobs')

# Example from jobs.py file
emit('error', json.dumps({"status_code": r.status_code}), namespace='/jobs')

I also specified the namespaces on the Angular files as such:

// class used to handle the sockets of the '/jobs' namespace
export class SocketJobs extends Socket {
  constructor() {
    super({ url: socketio_url + '/jobs', options: { autoConnect: false } });
  }
}

// more code //

this.socket.emit('getter', {
          // json //
        });

Upvotes: 0

Related Questions