何为socketIO,何为Websocket: #
Websocket是什么 #
WebSocket是为解决客户端与服务端实时通信而产生的技术。其本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接, 此后服务端与客户端通过此TCP连接进行实时通信。
SockectIO又是什么? #
简单说是对websocket的协议的封装,客户端SocketIO能够更简单的方法实现这一协议,并且如果浏览器使用的老式的浏览器,也能通过使用长链 接的方式实现相同的效果.服务端对各大语言支持也非常不错.而且极容易使用
为何使用Websocket: #
首先看需求: #
- 我们的爬虫需要到目标网站每分钟爬取实时内容.
- 内容需要及时发送我们的网站上
那么收先解决的问题就是爬虫如何通知服务端,服务端如何推送至浏览器的问题.
ajax轮询方式: #
我们web一直都是请求->响应的模型,怎么才能内容推送至客户端,ajax轮询就是通过脚本,每隔一段时间向服务端发送请求,于是我们就看到了 如下的情况:
客户端: hi,服务端有新数据吗?
服务端:没有哦,
一分钟…
客户端:hi,有新数据更新吗?
服务端:没有哦
又一分钟过去了……
客户端: hi,有新数据吗?
服务端:你烦不烦啊,没有啊,
一分钟后….
客户端:hi,有数据吗?
服务端:有了有了,给你了,好烦啊
看到了吧,首先,每次http的请求都相当耗时耗流量,而且这种模型极为损耗性能,那么,什么办法才能解决呢,于是HTML5的新协议,websocket应对这种需求 应运而生…
Websocket的方式: #
如果改用了Websocket的方式我们就变成了这样的情景
客户端:hi,在吗?
服务端:恩,在,你在吗?
客户端,恩,我在,有信息记得通知我哦,我就呆这里不走了,
服务端:好,我这边有信息了,给你,你有什么告诉我的吗?
客户端: 没啥告诉你的….
……..
显然,这样的方式,应对这种需求就变得更加高效,那么我们该如何时使用呢?
使用: #
这里用python来实现,首先需要使用以下的包:
- flask-SocketIO
- SocketIO_client
- js的SocketIO_client
然后我们看看我们的实现原理图:
爬虫端: #
class NewsObserver(Observer):
def update(self):
logger_kxt.info(u"开始爬取")
news = NewsSpiderNews().spiderfirstNews()
socketIO = SocketIO('localhost', 5000) #定义websocket的服务器
for new in news:
news_obj = News.objects(news_id=new.news_id).first()
if news_obj == None:
new.save()
logger_kxt.info(u'实时新闻:%s:%s更新成功'%(new.time,new.content))
msg_namespace = socketIO.define(BaseNamespace) #socketIO命名空间
msg_namespace.send(str(new.news_id)) # 发送信息
else:
logger_kxt.info(u'实时新闻:暂无更新')
socketIO.disconnect() # 本次信息发送完成后断开链接
服务端: #
from app import socketio
from common.logger import logger_zwoil
# 接受爬虫推过来的数据推送至客户端!
@socketio.on('message')
def handle_message(message):
logger_zwoil.info(u'received message: ' + message)
news = News.objects(news_id=int(message().first()
socketio.emit('my response', data, broadcast=True)#将信息广播所有客户端
logger_zwoil.info(u'push successfully')
浏览器客户端: #
-
首先,我们要将SockeIo依赖添加到html内:
<script type="text/javascript" src="/static/js/jquery.min.js" charset="utf-8"></script> <script type="text/javascript" src="/static/js/socket.io-1.4.5.js" charset="UTF-8"></script> -
然后使用:
var news = io("http://127.0.0.1:5000/"); news.on("news",function (data) { console.log(data); $(".news").prepend("<li>"+data+"</li>") }); -
完整的html代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新闻列表</title> <script type="text/javascript" src="/static/js/jquery.min.js" charset="utf-8"></script> <script type="text/javascript" src="/static/js/socket.io-1.4.5.js" charset="UTF-8"></script> </head> <body> <script> var news = io("http://127.0.0.1:5000/"); news.on("news",function (data) { console.log(data); $(".news").prepend("<li>"+data+"</li>") }); </script> <ul class="news"> <li>这些都是原来的新闻</li> </ul> </body> </html>
结语: #
使用SocketIO能干许多事情,可以利用这一协议,推流,推信息,聊天,甚至网络游戏也可以这样实现,更多使用,请看官方文档,介绍的都很详细: