Проблема на самом деле заключается в перегрузчике Flask.
Когда у вас включен режим отладки, по умолчанию Flask будет использовать перегрузчик - процесс, который отслеживает файлы вашего приложения и перезапускает сервер при их изменении.,По этой причине, когда Flask запускает строку socketio.run
и определяет, что режим отладки должен быть включен, он перезапускает скрипт .
Это означает, что фоновые потоки будут запущены снова.Но у вас уже есть работающий поток, связанный с UDP 127.0.0.1:5005.Вторая попытка сделать это не удастся:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\matejcik\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Users\matejcik\AppData\Local\Programs\Python\Python37\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File ".\app.py", line 23, in background_thread
sock.bind((UDP_IP, UDP_PORT))
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Старый поток UDP все еще существует, получит сообщения UDP и распечатает их на консоль. Но этот поток до перезапуска все еще ссылается на старую среду Python, поэтому экземпляр socketio устарел, посылая сообщения в void.
Это также причина, почему ZMQ получает сообщения нормально:поскольку подписка ZMQ не является эксклюзивной, можно запустить как старый, так и новый поток, и новый поток сможет без проблем передавать сообщения в новое гнездо.
В общем, взаимодействие потоков и перегрузчикагрязный, см. также https://github.com/miguelgrinberg/Flask-SocketIO/issues/567
Вы можете избежать этой проблемы, указав debug=False
или debug=True, use_reloader=False
.