5 changed files with 190 additions and 4 deletions
@ -1,9 +1,10 @@ |
|||||
from .middleware import Middleware |
from .middleware import Middleware |
||||
|
from .namespace import Namespace |
||||
from .base_manager import BaseManager |
from .base_manager import BaseManager |
||||
from .pubsub_manager import PubSubManager |
from .pubsub_manager import PubSubManager |
||||
from .kombu_manager import KombuManager |
from .kombu_manager import KombuManager |
||||
from .redis_manager import RedisManager |
from .redis_manager import RedisManager |
||||
from .server import Server |
from .server import Server |
||||
|
|
||||
__all__ = [Middleware, Server, BaseManager, PubSubManager, KombuManager, |
__all__ = [Middleware, Namespace, Server, BaseManager, PubSubManager, |
||||
RedisManager] |
KombuManager, RedisManager] |
||||
|
@ -0,0 +1,91 @@ |
|||||
|
import types |
||||
|
|
||||
|
|
||||
|
class Namespace(object): |
||||
|
"""A container for a set of event handlers for a specific namespace. |
||||
|
|
||||
|
A method of this class named ``on_xxx`` is considered as the event handler |
||||
|
for the event ``'xxx'`` in the namespace this class is registered to. |
||||
|
|
||||
|
There are also the following methods available that insert the current |
||||
|
namespace automatically when none is given before they call their matching |
||||
|
method of the ``Server`` instance: |
||||
|
``emit``, ``send``, ``enter_room``, ``leave_room``, ``close_room``, |
||||
|
``rooms``, ``disconnect`` |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
from socketio import Namespace, Server |
||||
|
|
||||
|
class ChatNamespace(Namespace): |
||||
|
def on_msg(self, sid, msg): |
||||
|
# self.server references to the socketio.Server object |
||||
|
data = "[%s]: %s" \ |
||||
|
% (self.server.environ[sid].get("REMOTE_ADDR"), msg) |
||||
|
# Note that we don't pass namespace="/chat" to the emit method. |
||||
|
# It is done automatically for us. |
||||
|
self.emit("msg", data, skip_sid=sid) |
||||
|
return "received your message: %s" % msg |
||||
|
|
||||
|
# Here we set the event name explicitly by decorator. |
||||
|
@Namespace.event_name("event name with spaces") |
||||
|
def foo(self, sid): |
||||
|
# ... |
||||
|
|
||||
|
sio = socketio.Server() |
||||
|
sio.register_namespace("/chat", ChatNamespace) |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, name, server): |
||||
|
self.name = name |
||||
|
self.server = server |
||||
|
|
||||
|
# wrap methods of Server object |
||||
|
def get_wrapped_method(func_name): |
||||
|
def wrapped_func(self, *args, **kwargs): |
||||
|
"""If namespace is None, it is automatically set to this |
||||
|
object's one before the original method is called. |
||||
|
""" |
||||
|
if kwargs.get('namespace') is None: |
||||
|
kwargs['namespace'] = self.name |
||||
|
return getattr(self.server, func_name)(*args, **kwargs) |
||||
|
return types.MethodType(wrapped_func, self) |
||||
|
for func_name in ('emit', 'send', 'enter_room', 'leave_room', |
||||
|
'close_room', 'rooms', 'disconnect'): |
||||
|
setattr(self, func_name, get_wrapped_method(func_name)) |
||||
|
|
||||
|
def get_event_handler(self, event_name): |
||||
|
"""Returns the event handler for given ``event`` in this namespace or |
||||
|
``None``, if none exists. |
||||
|
|
||||
|
:param event: The event name the handler is required for. |
||||
|
""" |
||||
|
for attr_name in dir(self): |
||||
|
attr = getattr(self, attr_name) |
||||
|
if hasattr(attr, '_event_name'): |
||||
|
_event_name = getattr(attr, '_event_name') |
||||
|
elif attr_name.startswith('on_'): |
||||
|
_event_name = attr_name[3:] |
||||
|
else: |
||||
|
continue |
||||
|
if _event_name == event_name: |
||||
|
return attr |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def event_name(name): |
||||
|
"""Decorator to overwrite event names: |
||||
|
|
||||
|
@Namespace.event_name("event name with spaces") |
||||
|
def foo(self, sid, data): |
||||
|
return "received: %s" % data |
||||
|
|
||||
|
Note that this must be the last decorator applied on an event handler |
||||
|
(last applied means listed first) in order to work. |
||||
|
""" |
||||
|
def wrapper(handler): |
||||
|
def wrapped_handler(*args, **kwargs): |
||||
|
return handler(*args, **kwargs) |
||||
|
wrapped_handler._event_name = name |
||||
|
return wrapped_handler |
||||
|
return wrapper |
Loading…
Reference in new issue