通过gevent-socketio为TurboGears提供SocketIO支持
项目描述
关于tgext.socketio
tgext.socketio提供了一种在TurboGears2中实现SocketIO的简单方法。通过gevent-socketio提供SocketIO支持,并提供了基于gevent的特定SocketIO服务器。
安装
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,因此您可以在RootController下挂载一个SocketIOController子类,或者您可以在任何其他位置挂载它并更改您的socketio_resource选项。
使用SocketIOController
SocketIOController的工作方式类似于任何其他TurboGears控制器,但支持作为子控制器服务SocketIOTGNamespace。 SocketIOController还可以像任何其他TG控制器一样表现,并提供普通网页。
SocketIOTGNamespace 是 socketio.namespace.Basenamespace 的子类,具有额外的 TurboGears 功能,如 @validate 和 @require 支持。请注意,SocketIOTGNamespace 至少需要 TurboGears 2.3.1,如果您想使用之前的 TurboGears 版本,仍然可以使用带有纯 socketio.namespace.Basenamespace 类的 SocketIOController。
使用示例
以下是一个非常简单的示例,处理两种类型的事件 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 TurboGears 装饰器。
相同的示例可以修改为通过几行代码提供验证和权限检查
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 内置了对基于 anypubsub 库的 PubSub 模式的支持。如果您想使用 PubSub,应通过 pip install anypubsub 安装 anypubsub 或将其添加到您的项目依赖项中。
PubSub 支持通过从 tgext.socketio.pubsub.PubSubTGNamespace 继承来实现。这个特殊的命名空间允许客户端通过从 JavaScript 接口调用 socket.emit('subscribe', 'channel_name') 来订阅频道。
每当用户订阅频道时,PubSubTGNamespace 子类将收到对 subscribe_channelname 方法的调用,该方法可以返回用户是否有权订阅指定的频道(可以使用 @require 装饰器)。subscribe_channelname 方法还可以返回不同的频道名称,如果您想指定子频道。
对于在订阅的频道上发布的每条消息,PubSubTGNamespace 将发出一个 pubblication 事件,该事件可以被 socket.io 客户端捕获以执行所需操作。
通过 PubSubTGNamespace.publish 可以发布消息。
您可以在 examples/chat.py 中看到一个简单的示例,该示例提供了一个在 redis 后端实现的实时聊天。
tgext.socketio-0.0.3.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 488c344a20610944fc58cdb526e2bf3b3cd837146d68393cfbbbb4a77a6b47ed |
|
MD5 | acc50ef775aaf8eb79742142cb469eb1 |
|
BLAKE2b-256 | 36d6a45823cad31c259ba1ab90e722c54cf12eef21e9ef9eb5793b1378d0885c |