通过gevent socketio为涡轮齿轮提供socketio支持
tgext.socketio的Python项目详细描述
关于tgext.socketio
socketio提供了在turbogears2中实现socketio的简单方法。 socketio支持由gevent socketio和特定的socketio服务器提供 提供基于gevent的。
安装
tgextsocketio可以从pypi安装:
pip install tgext.socketio
运行
socketio支持需要基于gevent的自定义http服务器才能工作 正确,请记住编辑development.ini并添加:
# SOCKETIO doesn't work with debug mode debug = false [server:main] use = egg:tgext.socketio#socketio socketio_resource = socketio host = 127.0.0.1 port = 8080
tgext.socketio#socketio是tgext.socketio提供的服务器 要正确支持socketio,而socketio_resource是 您的SocketIOController类的路径。
默认情况下,使用socketio,以便可以装载SocketIOController 在RootController下的子类,或者可以将其装载到任何其他位置 更改socketio_resource选项。
使用socketiocontroller
SocketIOController与任何其他涡轮齿轮控制器一样工作,但支持 将SocketIOTGNamespace用作子控制器。SocketIOController罐 也可以像其他tg控制器一样工作,并提供正常的web页面。
SocketIOTGNamespace是socketio.namespace.Basenamespace的子类 其他TurboGears功能,如^{TT14}$和^{TT15}$支持。 请记住SocketIOTGNamespace至少需要涡轮齿轮2.3.1, 如果您想使用以前的涡轮齿轮版本,您仍然可以使用SocketIOController 使用普通的socketio.namespace.Basenamespace类。
使用示例
下面是一个非常简单的示例,它处理两种类型的事件 ping和fireball并实时响应这些:
from tgext.socketio import SocketIOTGNamespace, SocketIOController class PingPong(SocketIOTGNamespace): def on_ping(self, attack): if attack['type'] == 'fireball': for i in range(10): self.emit('pong',{'sound':'bang!'}) else: self.emit('pong',{'sound':'pong'}) class SocketIO(SocketIOController): pingpong = PingPong @expose() def page(self, **kw): return ''' <html> <body> <div> <a class="ping" href="#" data-attack="ping">Ping</a> <a class="ping" href="#" data-attack="fireball">Fireball</a> <a class="ping" href="#" data-attack="auto">Auto</a> <a class="ping" href="#" data-attack="error">Error</a> </div> <div id="result"></div> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script> <script> $(function(){ var socket = io.connect('/pingpong', {'resource':'socketio'}); socket.on('pong',function(data){ $('#result').append(data.sound + '<br/>'); }); socket.on('error',function(error, info) { if (error == 'method_access_denied') { alert(info); } else { console.log(info); alert(error); } }); $('.ping').click(function(event){ event.preventDefault(); socket.emit('ping',{'type':$(this).data('attack')}); }); }); </script> </body> </html> ''' class RootController(BaseController): socketio = SocketIO()
请记住SocketIOController必须安装在同一位置 由配置文件中的socketio_resource属性指定。
使用验证器和需求
SocketIOTGNamespace还支持使用@validate和 @require涡轮齿轮装饰器。
同样的例子可以更改为提供验证和 使用几行代码进行权限检查:
from tg import validate, require, predicates from tg.validation import TGValidationError import random class NoFireBallValidator(object): def to_python(self, value, *args, **kw): type_ = value['type'] if type_ == 'auto': return {'type': random.choice(['ping', 'fireball'])} elif type_ == 'error': raise TGValidationError('Got an error!') return value class PingPong(SocketIOTGNamespace): @require(predicates.not_anonymous()) @validate({'attack': NoFireBallValidator()}) def on_ping(self, attack): if attack['type'] == 'fireball': for i in range(10): self.emit('pong',{'sound':'bang!'}) else: self.emit('pong',{'sound':'pong'})
pubsub支持
tgext.socketio内置了对基于pubsub范式的 在anypubsub库上。如果要使用pubsub,应该安装 通过pip install anypubsub或将其添加到项目中的任何pubsub 依赖关系。
pubsub支持通过从^{tt29}进行子类化来工作$ 这个特殊的命名空间允许客户端使用 socket.emit('subscribe', 'channel_name')来自javascript接口。
每当用户订阅频道时,pubsubgnamespace子类将接收 对subscribe_channelname方法的调用,如果用户被允许,它可以返回 是否订阅给定的频道(可以使用@requiredecorator)。 如果需要,subscribe_channelname方法还可以返回不同的通道名 指定子频道。
对于在订阅的频道pubsubgnamespace上发布的每条消息,将发出 pubblication事件,可被socket.io客户端捕获以执行所需的 行动。
可以通过PubSubTGNamespace.publish发布消息。
您可以看到一个简单的示例,它提供了在redis后端实现的实时聊天 在examples/chat.py