Combining socketio and simple web server in same app using background task - python

I have this script:
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
socketio = SocketIO(app)
def run_server():
socketio.run(app)
#socketio.on('message')
def handleMessage(msg):
print('Message: ' + msg)
send(msg)
if __name__ == '__main__':
socketio.start_background_task(run_server)
Every time i'm running that script the program begin and finish immediately.
I want to have both a Web server and a SocketIO server at the same app.
Maybe by having a port that listens to simple HTTP requests and a port that listens for SocketIO requests.

I'm starting my server like this :
app = Flask(__name__)
socketio = SocketIO(app)
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0')
And you can mix your routes in your app so you can have something like this :
#app.route('/picture')
def picture():
"""
Generate a picture, save it, and send it to client
"""
path_picture = ironcar.picture()
print('path_picture : ', path_picture)
if path_picture:
r = send_file(path_picture,
as_attachment=True)
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
r.headers['Cache-Control'] = 'public, max-age=0'
return r
# ------- SOCKETS ----------
#socketio.on('mode_update')
def mode_update(mode):
"""
Change the driving mode of the car
"""
print('SERVER : mode: ' + mode)
ironcar.switch_mode(mode)

Related

Flask socketIO connection established but not routed

For my project I have to connect one socketIO backend to another. For this I am using Flask-socketio and socketio-client. The code for both is the following:
CLIENT:
from socketIO_client import SocketIO, LoggingNamespace
ip = '192.168.1.41'
port = 8090
def handle_aaa_response():
print('response')
socketIO = SocketIO(ip, port)
socketIO.on('pingSuccess', on_aaa_response)
socketIO.wait(seconds=1)
SERVER:
from flask import Flask, render_template, jsonify, Response
from flask_socketio import SocketIO, emit
TRACE_LIBRARIES = False
HOST = '0.0.0.0'
WEB_PORT = 8090
USE_PIN = False
def handle_connect():
print('hello world')
emit('pingSuccess')
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.config['DEBUG'] = True
socketio = SocketIO(app, cors_allowed_origins="*")
socketio.on('connect', handle_connect)
try:
socketio.run(app,
host=HOST,
port=WEB_PORT,
log_output=True)
except KeyboardInterrupt:
print('*** User raised KeyboardInterrupt')
exit()
When i run the client and server, the server only logs the following:
(4743) accepted ('192.168.1.33', 53500)
192.168.1.33 - - [21/Oct/2020 15:48:31] "GET /socket.io/?EIO=3&transport=polling&t=1603291711742-0 HTTP/1.1" 200 371 0.005033
(4743) accepted ('192.168.1.33', 53502)
This means the server is accepting the connection from the client, but not routing to the correct route on the server.
I want to know how I can change this so it gets to the correct route and prints "hello world:
Contrary to socketio.on() from the regular socketIO_client package you use in your client script, flask_socketio uses .on() as a decorator.
So to add a callback to an event in flask_socketio, you would need to change the following:
...
socketio = SocketIO(app, cors_allowed_origins="*")
#socketio.on('connect')
def handle_connect():
print('hello world')
emit('pingSuccess')
...
Server Side
#socketio.on('connect')
def test_connect():
print('hello world')
emit('pingSuccess')

Listening to multiple ports in socket io flask

Following is the code that I have for the socket server in node js
let express = require("express");
let http_server = require("http").Server(express());
let io_server = require("socket.io")(http_server);
let app = express();
let http_publisher = require("http").Server(app);
let io_publisher = require("socket.io")(http_publisher);
.
.
.
http_server.listen(3000, function () {
console.log("WebSocket: listening on *:3000");
});
http_publisher.listen(3001, function () {
console.log("HTTP server: listening on *:3001")
});
what is the python equivalent of the same code? I have tried the following but it just wont let me listen to two ports at the same time :(
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('my event')
def test_message(message):
emit('my response', {'data': 'got it!'})
if __name__ == '__main__':
socketio.run(app,port=3000)

Assign separate ports for http server and publisher

I'm using the following code for bidirectional communication. I would like to run the WebSocket's publisher at port 2001 and HTTP server at port 2000. Following is my code
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('my event')
def test_message(message):
emit('my response', {'data': 'got it!'})
if __name__ == '__main__':
socketio.run(app,port=2001)
How do I assign individual ports to both HTTP server and HTTP publisher?

Python sockets with flask and vue for continious serial data stream

So I have an flask application which is extended by the flask_socketio package.
I currently have a vue front end, that connects to an socket.
Now the output of the socket connection in the following:
I also see an connection in the terminal of the flask application:
127.0.0.1 - - [23/Aug/2019 21:07:11] "GET /socket.io/?EIO=3&transport=polling&t=Mo_u1wR HTTP/1.1" 200
However, I have on my code that when the socket connects, there should start an thread with while true, to continious receive the data.
This is the code I have:
from flask import Flask, jsonify
from flask_socketio import SocketIO, send, emit
import threading
from threading import Lock
import time
import controllers.gpsController
# configuration
DEBUG = True
# instantiate the app
app = Flask(__name__)
app.config.from_object(__name__)
thread = None
thread_lock = Lock()
async_mode = None
# app.config['SECRET_KEY'] = 'secret!'
# enable CORS
socketio = SocketIO(app, cors_allowed_origins='*', async_mode=async_mode)
def activate_gps():
ser = controllers.gpsController.open_serial_connection()
while True:
data = controllers.gpsController.readGPS(ser)
if data != None:
socketio.emit('fetch_gps_data', data, broadcast=True)
socketio.sleep(0.1)
# Use sockets here
#socketio.on('connect')
def start_get_data_thread():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(target=activate_gps)
if __name__ == '__main__':
socketio.run(app, host='127.0.0.1', port=12345)
Anyone an idea what I'm doing wrong here? If I have te code of activate_gps() in another file and call that, I get the wanted output.

How to run python-socketio (eventlet WSGI server) over HTTPS

I want to run the following eventlet WSGI server over HTTPS. I am trying to connect to the python server from JavaScript on my HTTPS enabled web-server.
I would like the answer to describe how I would change this code below to work with HTTPS.
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, render_template
sio = socketio.Server()
app = Flask(__name__)
#app.route('/')
def index():
"""Serve the client-side application."""
return render_template('index.html')
#sio.on('connect', namespace='/chat')
def connect(sid, environ):
print("connect ", sid)
#sio.on('chat message', namespace='/chat')
def message(sid, data):
print("message ", data)
sio.emit('reply', room=sid)
#sio.on('disconnect', namespace='/chat')
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
This code was take from here
To run a Evenlet WSGI server over HTTPS all that’s needed is to pass an SSL-wrapped socket to the server() method like so:
wsgi.server(eventlet.wrap_ssl(eventlet.listen(('', 8000)),
certfile='cert.crt',
keyfile='private.key',
server_side=True),
app)

Categories

Resources