代码之家  ›  专栏  ›  技术社区  ›  John WH Smith

Skype通过DBus API返回空CHATMESSAGES结果

  •  0
  • John WH Smith  · 技术社区  · 9 年前

    我正在尝试使用Skype的DBus API来检索我与联系人交换的消息列表(消息ID)。然而 SEARCH CHATMESSAGES <target> (方案>=3)和 SEARCH MESSAGES <target> (protocol<3)命令返回意外的空结果。

    下面是我与API进行的一些交流的痕迹。我用过 d-feet 发送请求,但当我从自己的程序发送请求时,结果完全相同。

    • 总线名称: com.Skype.API
    • 对象: /com/Skype
    • 接口: com.Skype.API公司
    • 使用的方法: Invoke(String request)

    跟踪:

    -> NAME dfeet
    <- OK
    -> PROTOCOL 8
    <- PROTOCOL 8
    -> SEARCH CHATMESSAGES mycontact
    <- 
    

    同样的事情发生在另外两个人身上 SEARCH 命令:

    • 搜索消息<目标> (带有 PROTOCOL 2 ).
    • SEARCH CHATS

    此外,当我尝试根据聊天ID请求消息列表时,也会得到一个空结果: GET CHAT <chat_id> GETMESSAGES .

    但是,诸如 SEARCH FRIENDS , SEARCH CALLS SEARCH ACTIVECHATS 工作正常,并按预期返回他们的ID列表(联系人ID、通话ID或聊天ID)。

    同样值得注意的是,无论我与联系人交换了多少信息,所有联系人都会出现这种情况(起初我认为可能涉及太多信息,但结果是一样的,无论我是否向联系人发送了3条或数千条信息)。

    对于这些请求,有什么可以解释为什么我通过DBus获得这些空响应吗?

    1 回复  |  直到 9 年前
        1
  •  2
  •   John WH Smith    9 年前

    Skype不会使用 Invoke 的返回值。 事实上,当Skype有太多的数据需要在请求后准备和传输时,它会自动向 援引 呼叫这个 真的,沉重的 然后,Skype异步地准备回复,客户端程序必须准备好在它最终到达时接收它。

    每当您通过DBus与Skype通信时,您的应用程序必须同时充当客户端(呼叫 援引 ),和服务器(为Skype提供DBus对象)。这个设计有点出乎意料(我想我们可能会对它的质量进行争论),但这是它需要你做的:

    1. 使您的程序成为DBus“服务器”(提供可访问的对象)。通过Skype的总线名称,注册一个名为 /com/Skype/Client 实施 com.Skype.API.Client 界面
    2. 为此接口的唯一方法准备消息处理程序: Notify(s) 。这是Skype将尝试调用的方法,以向您发送对您先前请求的沉重答复。
    3. 编程自己的机制以匹配 援引 异步请求 Notify 稍后会有消息作为答复。

    对象的创建可以通过 dbus_connection_register_object_path ,其参数为:

    • 这个 DBusConnection 表示总线名称的结构。
    • 您正在注册的对象路径,此处 /com/Skype/客户端 .
    • 消息处理程序表( DBusObjectPathVTable )用于处理所有传入请求。
    • 调用这些处理程序时要发送给它们的数据。 这是额外的数据,而不是实际收到的消息,因为您只是在这里设置处理程序。

    例如。。。

    DBusHandlerResult notify_handler(DBusConnection *connection, 
                                    DBusMessage *message, 
                                    void *user_data){
        return DBUS_HANDLER_RESULT_HANDLED;
    }
    
    void unregister_handler(DBusConnection *connection, 
                            void *user_data){}
    
    DBusObjectPathVTable vtable = {
        unregister_handler,
        message_handler,
        NULL
    };
    
    if(!dbus_connection_register_object_path(connection,
                                             "/com/Skype/Client",
                                             &vtable, NULL)){
        // Error...
    }
    

    注意,这只是一个对象的定义。为了 通知 电话,你必须 select() DBusWatch 文件描述符,并分派传入的 DBusMessage 以便调用消息处理程序。

    如果您正在使用其他绑定,您可能会找到更快的方法来设置对象并开始作为客户端应用程序工作。参见: