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

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)

Related

Closing flask-socket io server programmatically

I am new to server development so please be kind...
I am developing a test application that starts a flask-socketio server and after interacting with a clients, it needs to shutdown and open another instance.
However this is not possible
I get error
File "C:\Python39\lib\site-packages\eventlet\convenience.py", line 78, in listen
sock.bind(addr)
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
How can I programmatically shutdown the server?
I looked in answers here How to stop flask application without using ctrl-c and using a process indeed does the trick.
But I don't really want to have a separate process because sharing the variables between process is too tricky.
I also didn't understand from the same post how to send a request from the server to the server itself in order to shutdown the flask application.
This is an example of my code
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, render_template
import socket
import threading
import time
ip_addr=socket.gethostbyname(socket.gethostname())
appFlask = Flask(__name__)
sio = socketio.Server( ) #engineio_logger=True,logger=True)
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, appFlask)
#sio.on('connect')
def connect(sid, environ):
print('connect ', sid)
#sio.on('message')
def message(sid, data):
print('message '+data, data)
#sio.on('disconnect')
def disconnect(sid):
print('disconnect ', sid)
#sio.on('result')
def result(sid,data):
print('result ', sid)
def worker1():
socket_port=3000
eventlet.wsgi.server(eventlet.listen((ip_addr, socket_port)), app)
if __name__ == '__main__':
sio.start_background_task(worker1)
# do some stuff and interact with the client
sio.sleep(2)
# how can I close the server so that I can do the following?
sio.start_background_task(worker1)
EDITED wit flask socket io functionality
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, render_template
import socket
import threading
import time
import requests
from flask import request
from flask_socketio import SocketIO
ip_addr=socket.gethostbyname(socket.gethostname())
socket_port=3000
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
sio = SocketIO(app)
#app.route('/stop')
def stop():
sio.stop()
#sio.on('connect')
def connect(sid, environ):
print('connect ', sid)
#sio.on('message')
def message(sid, data):
print('message '+data, data)
#sio.on('disconnect')
def disconnect(sid):
print('disconnect ', sid)
#sio.on('result')
def result(sid,data):
print('result ', sid)
def worker1():
eventlet.wsgi.server(eventlet.listen((ip_addr, socket_port)), app)
if __name__ == '__main__':
eventlet_thr=sio.start_background_task(worker1)
# do some stuff and interact with the client
sio.sleep(2)
# now wait that the server is stopped
# invoke in a different process a request to stop
eventlet_thr.join()
# how can I close the server so that I can do the following?
sio.start_background_task(worker1)
You are using the eventlet web server is seems, so the question is how to stop the eventlet web server, Flask-SocketIO has nothing to do with the server.
As a convenience, Flask-SocketIO provides the stop() method, which you have to call from inside a handler. I'm not sure if that will work when the server is running on a thread that is not the main thread though, you'll have to test that out.
So basically what you need to do is add an endpoint that forces the server to exit, maybe something like this:
#app.route('/stop')
def stop():
sio.stop()
return ''
So then you can start and stop the server as follows:
if __name__ == '__main__':
thread = sio.start_background_task(worker1)
# do some stuff and interact with the client
requests.get('http://localhost:5000/stop')
thread.join()

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')

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?

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

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)

Python-SocketIO server won't emit from the main section of the program

I have a pyhton-socketio server that servers on port 8000 and handles connections perfectly. I want to emit the following emit message every 2 seconds. When emitting the client doesn't receive a message. If I emit from where I point out in the comment it works perfect.
How can I edit this to be able to emit from inside the while loop successfully?
The python server code:
import socketio
import eventlet
import threading
import time
from flask import Flask, render_template
sio = socketio.Server()
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
# as a decorator:
#sio.on('connect')
def connect_handler(sid, environ):
print('IP->' + environ['REMOTE_ADDR'])
# If I emit here it works e.g. sio.emit('status-update', {'core0_in': 8, 'core1_in': 12,'cpu_usage_in': 5, 'users': 7})
#sio.on('disconnect')
def disconnect(sid):
print('disconnect ', sid)
class Server(threading.Thread):
def __init__(self, thread_id):
threading.Thread.__init__(self)
self.threadID = thread_id
def run(self):
print("Starting " + self.name)
serve()
def serve():
if __name__ == '__main__':
global app
# wrap Flask application with socketio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
server_thread = Server("Server-thread")
server_thread.start()
while True:
print("Emitting...")
sio.emit('status-update', {'core0_in': 8, 'core1_in': 12,'cpu_usage_in': 5, 'users': 7}) # when emitting here the client doesn't receive anything
time.sleep(2)

Categories

Resources