PyZMQ Gevent Websocket Connection Error
Question: I am trying pub/sub pattern using python zmq. I am facing a strange problem on
the client side. On the client side I am using pyzmq, gevent-websocket and
bottle as wsgi server. Though it works perfectly for one client, the other
clients are waiting for the first client to disconnect. While working with one
client, if I disconnect and reconnect, I am getting the messages two times or
more for each reconnect.

    
    
    #!/usr/bin/python
    from gevent import monkey; monkey.patch_all()
    import zmq
    import gevent
    from bottle import route, run, request, abort, Bottle ,static_file
    from gevent import sleep
    from gevent.pywsgi import WSGIServer
    import geventwebsocket
    from geventwebsocket import WebSocketHandler, WebSocketError
    
    host = "127.0.0.1"
    port = 8000
    mqport = "8082"
    
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    
    app = Bottle()
    
    @app.route('/v1/streams/device/<id>')
    def handle_websocket(id):
        socket.setsockopt(zmq.UNSUBSCRIBE, '')
        socket.connect ("tcp://localhost:%s" % mqport)
        socket.setsockopt(zmq.SUBSCRIBE, id)
        wsock = request.environ.get('wsgi.websocket')
        if wsock is None:
            logger.info("Error creating websocket")
        try :
            while True:
                string = socket.recv()
                logger.info("%s" % string)
                id, data = string.split("  ")
                wsock.send("%s" % data)
                sleep(0.1)
        except geventwebsocket.WebSocketError, ex:
            wsock.close()
            sock.close()
    server = WSGIServer((host, port), app,
                    handler_class=WebSocketHandler)
    server.serve_forever()
    

All the examples I have seen use while loop for receiving the messages. I am
not comfortable with this while loop and looking for some call back function
like socket.on_message. For experimental purpose I wrote a node.js version of
the same without the while loop like this but in my project node is ruled out.
The node version is here:

    
    
    var WebSocketServer = require('websocket').server;
    
    var http = require('http');
    
    global.client = 0;
    
    var server = http.createServer(function(request, response) {
    
    });
    
    server.listen(8000, function() { });
    
    wsServer = new WebSocketServer({
    
        httpServer: server
    
    });
    
    
    
    // WebSocket server
    
    wsServer.on('request', function(request) {
    
        console.log("connected client :", global.client++)
    
        var connection = request.accept(null, request.origin); 
    
        var url = request.resourceURL.href
    
        var device_id = url.substr(url.lastIndexOf('/') + 1)
    
        var zeromq = require('zmq');
    
        var sock = zeromq.socket('sub');
    
        sock.connect('tcp://127.0.0.1:8082');
    
        sock.subscribe(device_id);
    
        sock.on('message', function(data) {
            console.log(data.toString());
    
            var msg = data.toString();
    
            var rjson = msg.split("  ") 
    
            connection.send(rjson.pop());
    
        });
    
        connection.on('close', function(connection) {
        });
    });
    

Here I dont use the while Loop.

What I am doing wrong on my python code?


Answer: After hitting the wall on several days we find a non-blocking zeromq client
called gevent-zeromq.

Lesson is anybody using gevent-websocket with zmq client don't use pyzmq but
use gevent-zeromq.

Now the gevent-zeromq is merged with pyzmq. Intead of doing `import zmq` do
`from zmq.green import zmq`

