Saturday, August 13, 2016

Websocket integration with Rest API : sample application -I

Websocket is an independent TCP based protocol. Web socket establishes a persistent connection between client and server, both can send data at  any time.

Server side implementation responsible for keeping large number of connections open, with high concurrency and low performance cost.Mostly based on non blocking  IO or threading. 

In this blog, we will go though Tornado, a Python implementation  for web socket connections.

In this example , we create a websocket server which keeps pinging a rest api at fixed interval and it will push the response whoever is connected with.

from tornado import websocket, web, ioloop, gen
import json
import urllib
import urllib2
import threading

cl = []

class IndexHandler(web.RequestHandler):
    def get(self):
        self.render("index.html")

class SocketHandler(websocket.WebSocketHandler):
    def check_origin(self, origin):
        return True

    def doWork(self):
        print "in  f()..."
        url = 'http://localhost:8080/rest/v1/echo/11?'
        username = 'admin'
        password = 'admin'
        p = urllib2.HTTPPasswordMgrWithDefaultRealm()
        p.add_password(None, url, username, password)
        handler = urllib2.HTTPBasicAuthHandler(p)
        opener = urllib2.build_opener(handler)
        urllib2.install_opener(opener)
        value = urllib2.urlopen(url).read()
       
        data = json.dumps(value)
        for c in cl:
            c.write_message(data)
        # call doWork() again in 230 seconds
        threading.Timer(230, self.doWork).start()

    def open(self):
        if self not in cl:
            cl.append(self)

        print "in  self()..."
        self.f();
        
    def on_close(self):
        if self in cl:
            cl.remove(self)
            
    def synchronous_fetch():
        print "Doing stuff..."
        url = 'http://localhost:8080/rest/v1/pingserver'
        http_client = HTTPClient()
        response = http_client.fetch(url)
        return response.body
    
class ApiHandler(web.RequestHandler):

#approach II
    @web.asynchronous
    def get(self, *args):
        self.finish()
        url = 'http://localhost:8080/rest/v1/pingserver'
        value = urllib2.urlopen(url).read()
        id = self.get_argument("id")
        value=response
        data = {"id": id, "value" : value}
        data = json.dumps(data)
        for c in cl:
            c.write_message(data)

    @web.asynchronous
    def post(self):
        pass

app = web.Application([
    (r'/', IndexHandler),
    (r'/ws', SocketHandler),
    (r'/api', ApiHandler),
    (r'/(favicon.ico)', web.StaticFileHandler, {'path': '../'}),
    (r'/(web_socket_rest_api.png)', web.StaticFileHandler, {'path': './'}),
])

if __name__ == '__main__':
    app.listen(8888)
    ioloop.IOLoop.instance().start()

No comments:

Post a Comment