socketio的应用

先把背景说清楚吧:

这两天要为web端做一个实时数据显示的需求。就是web端的数据通过websocket的方式来实时拉取。

结合需求研究了下,觉得socketio的比较简单,因为服务端的数据还要从其他网站抓回来,对方用的就是socketio。这玩意貌似服务端是nodejs的。我就找找有没有python版的。最后用以下这东西来做服务端。

https://pypi.python.org/pypi/python-socketio/1.6.1

 数据来源也用python来做客户端抓取吧。用这个: 
  

https://pypi.python.org/pypi/socketIO-client

工具背景介绍完了,就说下基本逻辑吧。

1.写一个程序到其他网站抓数据,拿到后放到Redis消息队列。

2.我们的web端连接到自己的socketio的服务端

3.自己的服务端从redis队列获取到数据后,直接广播给所有的web端。


抓取端的代码:

def on_message(*args):
    # 框架会自动解析出dict
    TickHelper.handle(args)


def on_connect():
    logging.info("success connect server")

def on_disconnect():
    logging.info("disconnect from server")

def on_reconnect():
    logging.info("reconnect to server")

def on_emit(*args):
    logging.info("success emit")

def run(host,port):
    socketIO = SocketIO(host,port
                        , headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36'}
                        )
    socketIO.on('connect', on_connect)
    socketIO.on('disconnect', on_disconnect)
    socketIO.on('reconnect', on_reconnect)

    socketIO.emit('',on_emit)#随便提交一个啥都可以。
    socketIO.on('message', on_message)
    #wait forever
    socketIO.wait()

socketio的事件模型还是蛮酷的。

下面是上文handle函数的逻辑,其实很简单,就是通过redis,送到队列里。

mgr = socketio.RedisManager('redis://xxx.xxx.xxx.xx:6379/0',write_only=True)#对于socketio来说,因为这里我没有receive需要,所以改为write_only

def handle(msg):
    mgr.emit("message", msg, room='tick')#这个room的概念很不错,相当于group的情况,可以对这个room进行广播


这样就把数据放到redis里啦。


下面就是服务端啦。

eventlet.monkey_patch()#切记要加,否则一辈子出不来数据
mgr = socketio.RedisManager('redis://xxx.xxx.xxx.xxx:6379/')#这里的redis的topickey,代码里有默认了socketio。这里可不能write_only哦。
sio = socketio.Server(async_handlers=True, logger=True,client_manager=mgr)
#通过到这里的设置,socketio则能自动接收上面抓取端推送的数据,自动推送给我们的web端了。

@sio.on('connect', namespace='/')
def connect(sid, environ):
    sio.enter_room(sid=sid,room="tick")#吧客户端放到组里
    logging.info("connect "+sid)


@sio.on('tick_request', namespace='/')
def message(sid):
    pass


@sio.on('disconnect', namespace='/')
def disconnect(sid):
    logging.info('disconnect '+sid)

if __name__ == '__main__':
    init_logger()
    app = socketio.Middleware(sio)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 8000)), app)



切记切记,eventlet框架,不能再用python自己的thread来做什么处理。否则代码都会挂在你的thread里,eventlet啥都不管了。



你可能感兴趣的:(socketio的应用)