-
-
Save ericremoreynolds/dbea9361a97179379f3b to your computer and use it in GitHub Desktop.
<html> | |
<body> | |
<h1>I feel lonely</h1> | |
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.3.min.js"></script> | |
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script> | |
<script type="text/javascript" charset="utf-8"> | |
var socket = io.connect('http://' + document.domain + ':' + location.port); | |
socket.on('connect', function() { | |
socket.emit('connected'); | |
}); | |
socket.on('message', function(data) { | |
$('h1').text(data) | |
}); | |
</script> | |
</body> | |
</html> |
from flask import Flask, request | |
from flask.ext.socketio import SocketIO | |
app = Flask(__name__, static_folder='') | |
io = SocketIO(app) | |
clients = [] | |
@app.route('/') | |
def index(): | |
return app.send_static_file('client.html') | |
@io.on('connected') | |
def connected(): | |
print "%s connected" % (request.namespace.socket.sessid) | |
clients.append(request.namespace) | |
@io.on('disconnect') | |
def disconnect(): | |
print "%s disconnected" % (request.namespace.socket.sessid) | |
clients.remove(request.namespace) | |
def hello_to_random_client(): | |
import random | |
from datetime import datetime | |
if clients: | |
k = random.randint(0, len(clients)-1) | |
print "Saying hello to %s" % (clients[k].socket.sessid) | |
clients[k].emit('message', "Hello at %s" % (datetime.now())) | |
if __name__ == '__main__': | |
import thread, time | |
thread.start_new_thread(lambda: io.run(app), ()) | |
while True: | |
time.sleep(1) | |
hello_to_random_client() |
@jeffthemaximum I suppose it's to avoid to send one million message per second (because without it'll go as fast as your CPU can handle it ==> Very Quick)
Isn't 'request.namespace' a string or I am missing something ? Not only it doesn't have socket method, but also you can't get a string to emit messages.
So this is outdated as of flask-socketio 1.0.
The 0.x releases exposed the gevent-socketio connection as request.namespace. In release 1.0 this is not available anymore. The request object defines request.namespace as the name of the namespace being handled, and adds request.sid, defined as the unique session ID for the client connection, and request.event, which contains the event name and arguments.
source: source
I'm still looking into how to do this. The docs mention that a user is automatically added to their own "room" on connection. If I can get the ID of this room, then all I need to do is store that ID somewhere, and emit to it using: (I'm using quotes because my keyboard locale is fucked and I can't type backtick)
emit('foo', 'bar', room=connections[room_id])
This is all I know as of yet. I might remember to update this when I find the answer; If I don't, reply to me and I'll help you if I can.
Me again. Repo owner states his plans to use the session ID as the room name:
For the upcoming major release of this extension I'm planning to automatically create the individual client rooms. These will be given the name of the session ID, which is exactly what you suggested above.
miguelgrinberg/Flask-SocketIO#89
This has now been implemented. You can access the session ID with
request.sid
short example:
# Object that represents a socket connection
class Socket:
def __init__(self, sid):
self.sid = sid
self.connected = True
# Emits data to a socket's unique room
def emit(self, event, data):
emit(event, data, room=self.sid)
@socketio.on('connect')
def foo():
sockets[request.sid] = Socket(request.sid)
Now you can just store the sid in a way that represents the reason you want to emit to that socket specifically.
nice work
Guys, can't resolve
Unresolved attribute reference 'sid' for class 'Request'
Tryng to get request.sid
Found nothing helpful here
so say if a client want to change from room A to room B, how does it work? Does he have to leave a room first and join another room? if there something called change_room?
Dude, literally having problems with this same thing 2 years later, find this gist as the first result on google for "flask socketio send to specific client", and scroll down to see my own account giving the solution. I totally forgot!
That being said, it is worth noting that the socket id of a socket under a namespace is now formatted "/endpoint#id", and this room method requires you to parse the id out of that as far as I'm aware.
server_variables = {}
# route for socket connection
@SOCKETIO.on('connect', namespace='/test')
def test_connect():
if request.sid not in server_variables.keys():
server_variables[request.sid] = {'sid' : request.sid, 'stats' : 'connected'}
print(str(request.sid) + '=> Client Connected '
# to broadcaset to all but self
for k in server_variables.keys():
if k!= requst.sid:
emit('my response', {'data': 'This sid ' + str(request.sid) + ' just connected', 'stats' : 'RUNNING'}, room = k)
# to send only to first socket that was connected to this server
emit('my response', {'data': 'This sid ' + str(request.sid) + ' just connected','stats' : 'RUNNING'}, room = server_variables[server_variables.keys()[0]]['sid'])
# route for socket disconnection
@SOCKETIO.on('disconnect', namespace='/test')
def test_disconnect():
if request.sid in server_variables.keys():
server_variables[request.sid]['stats'] = 'disconnected'
print(str(request.sid) + '=> Client Disconnected '
works in my project https://github.com/saurabhrb/LIVE_TERMINAL_FLASK
I can't seem to get around this. "request.namespace" gives me a '/'. I tried to emit using the room argument by passing in the "request.sid" but that causes the emit to not work at all. Can anyone tell what I'm doing wrong?
Isn't 'request.namespace' a string or I am missing something ? Not only it doesn't have socket method, but also you can't get a string to emit messages.
I am stucked on that too. Can't figure what version to use in order to get the right API.
I tried this and works for me:
io.emit('message', "Hello at %s" % (datetime.now()), room=clients[k])
This clients[k]
is the ID of the conection... On cliente is socket.id
and in the server is request.sid
(This one you need to import from flask import request
)
I dont tried if puttin an array in room
will send to all clients in there...
@juniordnts worked perfectly, thanks!
room=self.sid
Me again. Repo owner states his plans to use the session ID as the room name:
For the upcoming major release of this extension I'm planning to automatically create the individual client rooms. These will be given the name of the session ID, which is exactly what you suggested above.
miguelgrinberg/Flask-SocketIO#89
This has now been implemented. You can access the session ID with
request.sid
short example:
# Object that represents a socket connection class Socket: def __init__(self, sid): self.sid = sid self.connected = True # Emits data to a socket's unique room def emit(self, event, data): emit(event, data, room=self.sid) @socketio.on('connect') def foo(): sockets[request.sid] = Socket(request.sid)
Now you can just store the sid in a way that represents the reason you want to emit to that socket specifically.
Great response! Short and concise! Thanks for the example.
I tried this and works for me:
io.emit('message', "Hello at %s" % (datetime.now()), room=clients[k])
This
clients[k]
is the ID of the conection... On cliente issocket.id
and in the server isrequest.sid
(This one you need to importfrom flask import request
)I dont tried if puttin an array in
room
will send to all clients in there...
Thanks, @juniordnts.
The above code worked for me finally, and here is my code.
Hope it helps others save time.
Hey random internet guy here trying to debug issues I'm having with socketio. Why did you put time.sleep(1) on line 36?