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?
Related
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')
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)
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)
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)
I would like to use gevent-socketio to send messages from a worker thread and update all connected clients on the status of the job.
I tried this:
from flask import Flask, render_template
from flask.ext.socketio import SocketIO, send, emit
import threading
import time
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('message')
def handle_message(message):
send(message, broadcast=True)
#app.route('/')
def index():
return render_template('index.html')
def ping_thread():
while True:
time.sleep(1)
print 'Pinging'
send('ping')
if __name__ == '__main__':
t = threading.Thread(target=ping_thread)
t.daemon = True
t.start()
socketio.run(app)
And it gives me this error:
RuntimeError: working outside of request context
How do I send messages from a function that doesn't have the #socketio.on() decorator? Can I use gevent directly to send messages to socketio?
From this section of the documentation:
Sometimes the server needs to be the originator of a message. This can be useful to send a notification to clients of an event that originated in the server. The socketio.send() and socketio.emit() methods can be used to broadcast to all connected clients:
def some_function():
socketio.emit('some event', {'data': 42})
This emit is not from from flask.ext.socketio import SocketIO, send, but instead called on your socketio variable from socketio = SocketIO(app). Had you done socketio_connection = SocketIO(app), then you'd be calling socketio_connection.emit() to broadcast your data.