0

I want to make a webapp which can only be edited by one client at the same time. I use flask and flask-socketio. After the authorized client leaves (disconnect event in socketio) the next should be able to edit things. Right now I have multiple calls to websockets and http gets not just one websocket. Because I have simple html forms as well I have to block incoming request too.

I could get the IP from a request object in a socketio event.

connected = None

@socketio.on('disconnect', namespace='/notifications')
def disconnect():
    global connected
    connected = None
    logger.info('Client disconnected')

@socketio.on('connect', namespace='/notifications')
def notifications():
    global connected
    if not request.headers.getlist("X-Forwarded-For"):
       ip = request.remote_addr
    else:
       ip = request.headers.getlist("X-Forwarded-For")[0]
    if connected is None:
        connected = ip, request.environ["REMOTE_PORT"]
        logger.info("Client connected. %s:%s", connected[0],connected[1])
        # do stuff
    else:
        logger.info("Blocked %s:%s", ip, request.environ["REMOTE_PORT"])

It looks like a bad approach to me...

wenzul
  • 3,948
  • 2
  • 21
  • 33
  • First, what should happen when the second client tries to edit? An error message, or it just blocks until it's freed up? – abarnert Nov 13 '14 at 01:05
  • Second, the obvious way to do this is with a lock, but what kind of lock to use depends on whether you're doing your own session binding or just stashing stuff in the builtin contexts; whether you're using greenlets, threads, or forks; etc. So, it's hard to write an answer without more information. – abarnert Nov 13 '14 at 01:07
  • @abarnert Thanks for your comment. Ideally I would make all input fields read only and block modifing requests on the server side. – wenzul Nov 13 '14 at 01:08
  • Now I just use flask and flask-socketio which uses greenlets I think? My approach would just be use a global variable but I don't know whats good. – wenzul Nov 13 '14 at 01:10
  • The input fields don't seem all that important; once you can lock things down to only one socketio connection at a time, you can just check (on the JS side, on the server, or both) that the socketio connection is up before allowing any changes to the fields, right? – abarnert Nov 13 '14 at 01:10
  • Right now I have multiple connectionsm websocket and simple http and ajax calls... so I would need a global thing :/ – wenzul Nov 13 '14 at 01:16
  • Right, either the socketio connection itself, or just an ownership flag, has to be global. And you probably an appropriate (thread, greenlet, or multiprocessing) `Lock` around that (and if the lock is just protecting a flag, it can just _be_ the flag). Then it's just a question of whether you want to block or fail if someone else has the lock, which comes down to whether you do a try-acquire (`blocking=False` in the `acquire` call) or not. – abarnert Nov 13 '14 at 01:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64829/discussion-between-wenzul-and-abarnert). – wenzul Nov 13 '14 at 01:41
  • Sorry, I'm in transit now, and I don't think I have much more information to give anyway, because I haven't used Flask all that much. – abarnert Nov 13 '14 at 02:15

0 Answers0