Comments (15)
Try the main branch of flask-socketio and let me know if that works better.
Note that your catch-all handler should be as follows:
@socketio.on('in', namespace='*')
def on_in_star(data):
print(f"--- IN; catchall ns = {request.namespace}, {data}\n")
In Flask-SocketIO you do not need to add the namespace as an argument, because you always get it in request.namespace
.
from flask-socketio.
Worked! Looks like it's doing everything I expect now, thanks!
from flask-socketio.
Monkey patch:
import types
old_geh = socketio.server._get_event_handler
socketio.server.old_geh = socketio.server._get_event_handler
def new_geh(self, event, namespace, *args):
sys.stderr.write(f"XXX e:{event} ns:{namespace}\n")
h, a = self.old_geh(event, namespace, *args)
sys.stderr.write(f">>> h:{h} a:{a}\n")
return h, a
socketio.server._get_event_handler = types.MethodType(new_geh, socketio.server)
stderr output:
XXX e:connect ns:/
>>> h:<function on_connect at 0x7fb810513370> a:(...)
from flask-socketio.
The connect
and disconnect
handlers are not dispatched to catch-all handlers, only user-defined events are.
from flask-socketio.
Hm is that intentional, or can they also be enabled? Without a connect
catch-all, it doesn't seem like dynamic / arbitrary namespaces would be possible, i.e. all allowable namespaces would have to be explicitly assigned to a handler.
That said, something weird is still going on (which is what prompted my other post miguelgrinberg/python-socketio#1334 in the first place): I've pared it down to this minimal server code. If a client connects on the default namespace then sends an "in" event , it gets lost with:
from flask import Flask, render_template, request
from flask_socketio import SocketIO
import sys
app = Flask(__name__)
socketio = SocketIO(app, namespaces="*")
@app.route('/')
def root():
return render_template('index.html')
@socketio.on('connect')
def on_connect(auth):
sys.stderr.write(f"*** IN CONNECT w/ default ns\n")
@socketio.on('in', namespace='*')
def on_in_star(ns, data):
sys.stderr.write(f"--- IN; catchall ns = {ns}, {data}\n")
if __name__ == '__main__':
socketio.run(app, debug=True)
The ns catchall does not get triggered. But if I add a ns-specific handler:
@socketio.on('in', namespace='/')
def on_in(data):
sys.stderr.write(f"/// IN; ns = '/', data = {data}\n")
that one does successfully get triggered.
For completeness, index.html:
<html>
<head>
<script src="/static/js/socket.io.min.js"></script>
</head>
<body>
<script>
const socket = io();
socket.on('connect', function() {
console.log("Connected to server, emitting 'hello' to 'in'");
socket.emit('in', 'hello')
});
</script>
</body>
</html>
from flask-socketio.
So your client is sending an event on a namespace it did not connect to? That does not work, the client must connect to the namespace(s) it wants to use.
from flask-socketio.
- The client connects to the default namespace (i.e. "/")
- The connection succeeds and the ns-specific connection handler is called.
- The client sends a message to an event on the connected sio (i.e. namespace = "/"). Either:
- The message gets successfully handled if there is a ns-specific event handler, or
- The message gets dropped if there is only a ns catch-all handler (and no ns-specific event handler). The catch-all handler does not get called. This is the bug.
(I'll split out the other issue into its own thread.)
from flask-socketio.
How is this different from the situation described in miguelgrinberg/python-socketio#1334, which we agreed that is working correctly?
from flask-socketio.
Yeah we agreed that it should work... but it doesn't. Again, here is a MWE, now all contained in a single file:
from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app, namespaces="*", logger=True, engineio_logger=True)
@app.route('/')
def root():
return '''<!DOCTYPE html>
<html>
<head><script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script></head>
<body><script>
const socket = io();
socket.on('connect', function() {
socket.emit('in', 'hello')
});
</script></body>
</html>
'''
@socketio.on('connect')
def on_connect(auth):
print(f"*** CONNECT; default ns\n")
@socketio.on('in', namespace='*')
def on_in_star(ns, data):
print(f"--- IN; catchall ns = {ns}, {data}\n")
if __name__ == '__main__':
socketio.run(app, debug=True)
If everything was working as intended, we would expect to see both print statements execute, i.e. if we see *** CONNECT; default ns
then we should also see --- IN; catchall ns = /, hello
. But we don't:
8S2llN_8QFMwcWC9AAAA: Sending packet OPEN data {'sid': '8S2llN_8QFMwcWC9AAAA', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
127.0.0.1 - - [08/May/2024 02:09:04] "GET /socket.io/?EIO=4&transport=polling&t=OzNTgOA HTTP/1.1" 200 -
8S2llN_8QFMwcWC9AAAA: Received packet MESSAGE data 0
*** CONNECT; default ns
8S2llN_8QFMwcWC9AAAA: Sending packet MESSAGE data 0{"sid":"qhmheUkfz-IN1VcHAAAB"}
127.0.0.1 - - [08/May/2024 02:09:04] "POST /socket.io/?EIO=4&transport=polling&t=OzNTgOR&sid=8S2llN_8QFMwcWC9AAAA HTTP/1.1" 200 -
8S2llN_8QFMwcWC9AAAA: Received request to upgrade to websocket
127.0.0.1 - - [08/May/2024 02:09:04] "GET /socket.io/?EIO=4&transport=polling&t=OzNTgOy&sid=8S2llN_8QFMwcWC9AAAA HTTP/1.1" 200 -
127.0.0.1 - - [08/May/2024 02:09:04] "GET /socket.io/?EIO=4&transport=polling&t=OzNTgOy.0&sid=8S2llN_8QFMwcWC9AAAA HTTP/1.1" 200 -
8S2llN_8QFMwcWC9AAAA: Upgrade to websocket successful
8S2llN_8QFMwcWC9AAAA: Received packet MESSAGE data 2["in","hello"]
received event "in" from qhmheUkfz-IN1VcHAAAB [/]
The received event should get dispatched to the in
handler in the catch-all namespace... but it does not.
from flask-socketio.
@miguelgrinberg Could you make a new release with this commit to save having to pip install from git? Thanks!
from flask-socketio.
Also, there may need to be a similar fix to allow catch-all event handling? I don't think I can successfully do a
@socketio.on('*')
(but I haven't tried very much yet)
from flask-socketio.
I have never spent the time to add catch-all handlers in this package, and there is currently no testing beyond what I added for this fix. Before I can release this as a supported feature I need to do some more work and build tests.
from flask-socketio.
Ah I see; thanks for your diligence!
from flask-socketio.
Please add catch all event handling. And on that subject, Please add dynamic event registering and unregistering at runtime.
from flask-socketio.
Please add dynamic event registering and unregistering at runtime.
Not planning to do this. You can implement this yourself for your application using a class-based namespace (or a catch-all event handler once I add them properly to this package) if this is important to you.
from flask-socketio.
Related Issues (20)
- Add type hints HOT 9
- Socket.IO test client does not run background task HOT 7
- gevent - cannot enter into function. HOT 1
- Multiple SocketIO instances connected to the same Flask server HOT 1
- python-engineio and python-socketio version matching with Flask-SocketIO >= 5.3.0 HOT 1
- Flask-SocketIO cannot run in ws HOT 1
- pyinstaller Packaging error HOT 1
- How do I intercept event events and authenticate them in a unified manner?
- Waiting for client events leads to timeouts
- Sending events in a separate thread with delays does not send HOT 1
- Sending high volume of packets in short amount of time causes packets dropping HOT 5
- Namespace catch-all handling of connect/disconnect events HOT 1
- Flask-SocketIO returns [] on `get_received` function call HOT 10
- Is Eventlet Still The Best Option? HOT 1
- Session not persisting between Flask and SocketIO
- support Access-Control-Allow-Private-Network headers
- Cassandra Requests Hang in Flask-SocketIO Development Mode HOT 15
- Handling CORS with Wildcard Subdomains in Flask-SocketIO HOT 1
- Gunicorn reload option doesn't work with flask-socketIO HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flask-socketio.