Hi all, I’ve made somewhat of a hack that I’d like to you by you to hear what you think of it.
In a nutshell, sending a request to a web-server is one way; you send, the server responds. It’s a “pull” relationthip. There’s *no way* to get the server to send any data to a client without it having asked for it, that’s why you’ve got things like socket.io and gevent <http://www.gevent.org/>. A “push” relationship. The hack then, is a way around this and assumes that you have control over both server and client. It works like this. *Sending a request from server-to-client* 1. The client makes an initial, regular request 2. The request is *not* responded to, but simply held on to; like a handle to the client 3. When the server is looking to make a request to the client, it simply responds. The handle can be held indefinitely, and may be re-established per response. Effectively allowing the server to make any amount of “requests” to the client. Here’s an implementation. """Request-response inversion Inverse the typical request-response pattern so as to allow a host to make requests to the client. Usage: # Terminal 1 # The client >>> import server >>> import threading >>> t = threading.Thread(target=server.app.run, kwargs={"threaded": True}) >>> t.start() # Terminal 2 # The host $ curl -X POST http://127.0.0.1:5000/dispatch ... blocking # Terminal 1 # Client sending "request" >>> server.queue.put("show") # Terminal 2 # Host receiving "request" {"status": "ok", "result": "Showing.."} Requests may be made *before* having been responded to. With that, we've got a true bi-directional communication link going. Usage: # Terminal 1 # The client >>> import server >>> import threading >>> t = threading.Thread(target=server.app.run, kwargs={"threaded": True}) >>> t.start() # Terminal 2 # First request from host $ curl -X POST http://127.0.0.1:5000/dispatch ... blocking # Terminal 3 # Second request from host $ curl -X GET http://127.0.0.1:5000/dispatch {"status": "ok", "queue": []} # Terminal 1 # Client sending "request" >>> server.queue.put("show") # Terminal 2 # Host receiving "request". {"status": "ok", "result": "Showing.."} """ # Standard libraryimport Queue # Third-party dependenciesimport flask app = flask.Flask(__name__) # This queue is used for communication between threads.# It'll be queried (and may be empty) by the client,# and filled by the host. When filled, the blocking query# is released and processed. queue = Queue.Queue() @app.route("/dispatch", methods=["GET", "POST"])def dispatch(): if flask.request.method == "GET": return flask.jsonify(status="ok", queue=list(queue.queue)) else: cmd = queue.get() if cmd == "show": return flask.jsonify(status="ok", result="Showing..") return flask.jsonify(status="fail", result="Command not recognised: %s" % cmd) ``` Technically, no requests are being made to the client. Practically on the other hand, any data can be sent, asynchronously, in both directions. Thoughts? Best, Marcus -- *Marcus Ottosson* [email protected] -- You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODcHdhVXYbc4yfY4CksU_wVm-VyhLRqzpU%2BGGPG9RFBAQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
