I've created a single socket endpoint on the server side that looks like this:
Server.py
from client import sockio_client
from flask_socketio import SocketIO
from flask import Flask
app = Flask(__name__)
socketio = SocketIO(app)
#socketio.on('status_update')
def status_update(data):
print('got something: ',data)
#app.before_first_request
def start_ws_client():
# now that server is started, connect client
sockio_client.connect('http://localhost:5000')
if __name__ == "__main__":
socketio.run(app,debug=True)
And the corresponding client:
Client.py
import socketio
from threading import Thread
sockio_client = socketio.Client()
# wait to connect until server actually started
# bunch of code
def updater():
while True:
sockio_client.emit('status_update', 42)
time.sleep(10)
t = Thread(target=updater)
t.start()
I've got a single background thread running outside of the server and I would like to update clients with the data it periodically emits. I'm sure there is more than one way to do this, but the two options I came up with were to either (i) pass a reference to the socketio object in server.py above to the update function in client by encapsulating the update function in an object or closure which has a reference to the socketio object, or (ii) just use a websocket client from the background job to communicate to the server. Option one just felt funny so I went with (ii), which feels... okish
Now obviously the server has to be running before I can connect the client, so I thought I could use the before_first_request decorator to make sure I only attempt to connect the client after the server has started. However every time I try, I get:
socketio.exceptions.ConnectionError: Connection refused by the server
At this point the server is definitely running, but no connections will be accepted. If I were to comment out the sockio_client.connect in server.py, and connect from an entirely separate script, everything works as expected. What am I doing wrong? Also, if there are much better ways to do this, please tear it apart.
Related
I have python_socketio 5.0.4 on client and Flask-SocketIO 5.0.1 on server. When client connects to server, I would like to synchronize client's SID between client and server. However, when I print SID on client, it's different from SID printed on server.
Is there any way to make SID of client same on server as on client?
Here is code for client:
import socketio
sio = socketio.Client()
sio.connect("http://localhost:5000")
print(sio.sid) # czNJ6NXIAXP9-vgmAAAK
sio.emit("test_event")
And here for server:
from flask import Flask, request
from flask_socketio import SocketIO
app = Flask(__name__)
sio = SocketIO(app)
#sio.on("test_event")
def test_event():
print(request.sid) # ukJhK9ZIiXY_gTMAAAL <--- this is different SID
sio.run(app)
The problem is that in the client you are accessing your sid as sio.sid. The sid property of the Socket.IO client is private, it is not supposed to be used.
Instead, use the sio.get_sid() method to obtain the sid. This used to not be a problem, but in the latest revision of the Socket.IO protocol each namespace is required to have a different sid, so the get_sid() method should be used to obtain the correct one for your namespace.
If you were using a non-default namespace you can pass it as an argument as follows: sio.get_sid(namespace='/my-namespace').
I am trying to host a simple websocket using Flask SocketIO with nothing but client disconnect and client connect command.
But I'm not sure what is not working properly.
Here is my server code
server.py
from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'very-secret'
socketio = SocketIO(app)
#socketio.on('connect')
def client_connect():
print("HII")
emit({'data': 'Hii'})
#socketio.on('disconnect')
def client_disconnect():
print('client disconnected')
#socketio.on('message')
def message(msg):
print(msg)
emit({'data':'lol'})
if __name__ == '__main__':
app.debug = True
socketio.run(app, port=2345)
When I start the server it says
Restarting with stat
Debugger is active!
Debugger PIN: 774-937-680
But doesn't say "Running on *********" message.
I am unable to find out what is the problem.
For client, I'm using some Chrome websocket client. The client connects but instantly disconnects.
I tried with Firefox websocket client too. Same thing with that.
Thank you in advance.
the syntax for emit is
emit(event,*args, **kwargs)
you haven't mentioned the event on which you want to emit the data. Try this might work
I am primarily a Javascript developer but I am trying to replicate a server I wrote in Node.js in Python. The server uses Socket.io to communicate with clients and I am having some trouble replicating this specific behaviour in Python:
io.on('connection', function(socket){
socket.on('disconnect', function(){ });
});
I would like to handle each client's events and messages separately from one another. Any way I could do this in Python? I am using the package flask_socketio to wrap the sockets. Cheers.
As far as I can see you just want connection and disconnection handlers?
You can do that as follows in Python:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
socketio = SocketIO(app)
#socketio.on('connect')
def connect():
# your connection logic here
#socketio.on('disconnect')
def disconnect():
# your disconnection logic here
if __name__ == '__main__':
socketio.run(app)
I have a websocket server using autobahn where it runs some code onMessage.
during this code an exception happens and I perform a try/except clause so I can log the error, it logs correctly. However the connection to the client(javascript) disconnects.
The problem is that if I load a new page it does not reconnect to the websocket server. I attempted to put the code block to start the server in a while loop but the client does not connect succesfully.
if __name__ == '__main__':
import sys
from twisted.python import log
from twisted.internet import reactor, task, threads
logging.basicConfig(filename='/var/log/myerror.log', level=logging.ERROR)
log.startLogging(sys.stdout)
factory = WebSocketServerFactory(u"ws://127.0.0.1:9000", debug=False)
factory.protocol = MyServerProtocol
factory.setProtocolOptions(maxConnections=50)
reactor.listenTCP(9000, factory)
reactor.run()
Does anyone know how to make it so even if the code in 'onMessage' has an exception, the websocket server will continue to accept connections and give other clients the opportunity to run?
Found the problem. I had placed 'reactor.callFromThread(reactor.stop) ' elsewhere in the code and it was killing the reactor.
My project use bottle and HBase, client connect to HBase via python thrift client, code simplify like this
#!/usr/bin/env python
from bottle import route, run, default_app, request
client = HBaseClient()
#route('/', method='POST')
def index():
data = client.getdata()
return data
Now the issue is if client disconnect, our request will be failed. So it requires to make sure client keep alive.
One solution is using connection pool, is there any connection pool I can refer to?
Any other solution for this issue?
Looks happybase can deal this issue
HappyBase has a connection pool that tries to deal with broken connections to some extent: http://happybase.readthedocs.org/en/latest/user.html#using-the-connection-pool