Server:
Ubuntu 18.04.3 LTS
python3.6
I want show device's message on web, my structure like:
Device--(MQTT)-->Server--(socket.io)-->Web
First, I publish message by mqtt to Server, and Server successed subscribed to get message .
Second, I use socket.io to send message to Web, but problem is here, if Server send message by socket.io after mqtt.on_message, the web's socket.io will be stuck, until refresh web.
My Flask Server a part of code:
from flask import Flask, request, render_template, flash, redirect, url_for
from flask_mqtt import Mqtt
from flask_socketio import SocketIO
from flask_bootstrap import Bootstrap
from flask_login import UserMixin, LoginManager, login_required, current_user, login_user, login_required, logout_user
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from forms import RegisterForm, LoginForm, AddForm, ChangePasswordForm
import pymysql
from config import Config
from sqlalchemy.ext.declarative import declarative_base
import json
import plotly as py
from datetime import datetime
import eventlet
eventlet.monkey_patch()
# MQTT
app = Flask(__name__)
bcrypt = Bcrypt(app)
app.config['SECRET'] = ''
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['MQTT_BROKER_URL'] = ''
app.config['MQTT_BROKER_PORT'] =
app.config['MQTT_USERNAME'] = ''
app.config['MQTT_PASSWORD'] = ''
app.config['MQTT_KEEPALIVE'] = 5
app.config['MQTT_TLS_ENABLED'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = ''
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
mqtt = Mqtt(app)
socketio = SocketIO(app, cors_allowed_origins='*')
if __name__ == '__main__':
socketio.run(app, keyfile='privkey.pem', certfile='fullchain.pem', host='0.0.0.0', port=5002, use_reloader=True, debug=True)
Flask Server MQTT and socket.io part of code:
@mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
mqtt.subscribe('test')
@mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
topic = message.topic,
raw_payload = message.payload.decode()
if(topic[0] == "test"):
socketio.emit('web', "received")
Web Client javascript code:
socket.on('web', function(data) {
console.log(data);
})
If just use socket.io to send message to web didn't use mqtt it's work fine. I don't know why they can't interact together. Then I find something on flask-mqtt offical file about "MQTT Interact with SocketIO", example code the difference from me is "import eventlet". So i guess is abotu threading problem? But when i also import it will show error, the error is:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/eventlet/hubs/hub.py", line 461, in fire_timers
timer()
File "/usr/local/lib/python3.6/dist-packages/eventlet/hubs/timer.py", line 59, in __call__
cb(*args, **kw)
File "/usr/local/lib/python3.6/dist-packages/eventlet/greenthread.py", line 221, in main
result = function(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 818, in process_request
proto.__init__(conn_state, self)
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 357, in __init__
self.handle()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 390, in handle
self.handle_one_request()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 419, in handle_one_request
self.raw_requestline = self._read_request_line()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 402, in _read_request_line
return self.rfile.readline(self.server.url_length_limit)
File "/usr/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 241, in recv_into
return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 256, in _base_recv
read = self.read(nbytes, buffer_)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 176, in read
super(GreenSSLSocket, self).read, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 146, in _call_trampolining
return func(*a, **kw)
File "/usr/lib/python3.6/ssl.py", line 874, in read
return self._sslobj.read(len, buffer)
File "/usr/lib/python3.6/ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
ssl.SSLWantReadError: The operation did not complete (read) (_ssl.c:2309)
I searched about this error, some result say this is eventlet's Bug on python3, Is any solution for this error?