示例#1
0
async def _handle_client_invoke(ws, cmd, impl):
    id_ = cmd['id']
    path = cmd['path']
    args = cmd['args']
    func = impl[path]

    result = {
        'type': 'invoke_result',
        'id': id_,
    }

    try:
        val = await _safe_invoke(func, *args)
        result['val'] = val

    except SerializeIface as s:
        sub_obj = s.obj
        sub_whitelist = s.whitelist_method_names
        sub_name = path + '.' + str(uuid.uuid4())
        sub_iface, sub_impl = serialize_interface(
            sub_obj, name=sub_name, whitelist_method_names=sub_whitelist)
        impl.update(sub_impl)
        result['iface'] = sub_iface

    except Exception as e:
        result['exception'] = str(
            e
        )  # TODO: Serialize the exception more fully so it can be stacktraced on the other side.

    result_buf = pack(result)
    await ws.send(result_buf)
示例#2
0
        async def unsubscribe_func():
            subscriptions[channel].remove(callback)

            if len(subscriptions[channel]) == 0:
                del subscriptions[channel]
                await ws.send(
                    pack({
                        'type': 'unsubscribe',
                        'channel': channel,
                    }))
示例#3
0
 async def handle_client(ws, path):
     root = root_factory()
     whitelist_method_names = ()
     if isinstance(root, tuple):
         root, whitelist_method_names = root
     iface, impl = serialize_interface(
         root, name='root', whitelist_method_names=whitelist_method_names)
     iface_buf = pack(iface)
     await ws.send(iface_buf)
     await ws.send(channels_buf)
     return await _handle_client(root, ws, impl, pubsub, subscribers)
示例#4
0
 async def publish_func(channel, payload, wait=False):
     client_list = subscribers.get(channel, [])
     if client_list:
         message = {
             'type': 'publish',
             'channel': channel,
             'payload': payload,
         }
         message_buf = pack(message)
         tasks = []
         for client in client_list:
             task = asyncio.create_task(client.send(message_buf))
             tasks.append(task)
         if wait:
             await asyncio.wait(tasks)
示例#5
0
def _build_client_handler(root_factory, pubsub, subscribers):
    channels = pubsub['channels'] if pubsub is not None else []
    channels_buf = pack(channels)

    async def handle_client(ws, path):
        root = root_factory()
        whitelist_method_names = ()
        if isinstance(root, tuple):
            root, whitelist_method_names = root
        iface, impl = serialize_interface(
            root, name='root', whitelist_method_names=whitelist_method_names)
        iface_buf = pack(iface)
        await ws.send(iface_buf)
        await ws.send(channels_buf)
        return await _handle_client(root, ws, impl, pubsub, subscribers)

    return handle_client
示例#6
0
    async def subscribe_func(channel, callback):
        if channel not in subscriptions:
            subscriptions[channel] = {callback}
            await ws.send(pack({
                'type': 'subscribe',
                'channel': channel,
            }))

        else:
            subscriptions[channel].add(callback)

        async def unsubscribe_func():
            subscriptions[channel].remove(callback)

            if len(subscriptions[channel]) == 0:
                del subscriptions[channel]
                await ws.send(
                    pack({
                        'type': 'unsubscribe',
                        'channel': channel,
                    }))

        return unsubscribe_func
示例#7
0
    async def impl_transport(path, args):
        nonlocal id_
        id_here = id_
        id_ += 1
        event = asyncio.Event()
        invoke_events[id_here] = {
            'event': event,
        }
        cmd = {
            'type': 'invoke',
            'id': id_here,
            'path': path,
            'args': args,
        }
        cmd = pack(cmd)
        await ws.send(cmd)
        await event.wait()
        message = invoke_events[id_here]['result_message']
        del invoke_events[id_here]

        if 'val' in message:
            return message['val']  # Standard return value

        elif 'exception' in message:
            error_text = message['exception']
            raise Exception(
                error_text)  # TODO: Rebuild the exception more precisely.

        elif 'iface' in message:
            sub_iface = message['iface']
            _, sub_proxy_iface = build_interface(sub_iface, impl_transport)
            return sub_proxy_iface

        else:
            raise Exception('Unknown response message...')

        return val