【问题标题】:Skype returning empty CHATMESSAGES results through the DBus APISkype 通过 DBus API 返回空的 CHATMESSAGES 结果
【发布时间】:2015-03-02 21:43:16
【问题描述】:

我正在尝试使用 Skype 的 DBus API 来检索我与联系人交换的消息列表(消息 ID)。但是,SEARCH CHATMESSAGES <target> (protocol >= 3) 和 SEARCH MESSAGES <target> (protocol

这是我与 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 命令也会发生同样的事情:

  • SEARCH MESSAGES &lt;target&gt;(与PROTOCOL 2)。
  • SEARCH CHATS

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

但是,SEARCH FRIENDSSEARCH CALLSSEARCH ACTIVECHATS 等命令可以正常工作,并按预期返回其 ID 列表(联系人 ID、呼叫 ID 或聊天 ID)。

可能还值得注意的是,无论我与他们交换了多少消息,所有联系人都会发生这种情况(我起初以为可能涉及的消息太多,但结果是一样的,无论我向联系人发送了 3 条还是数千条消息)。

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

【问题讨论】:

    标签: skype dbus


    【解决方案1】:

    当回复量过大时,Skype 不会使用Invoke 的返回值。 碰巧,当 Skype 在请求后准备和传输的数据过多时,它会自动返回Invoke 调用的空字符串。 真正的、沉重的回复随后由 Skype 异步准备,客户端程序必须准备好在它最终到达时接收它。

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

    1. 使您的程序成为 DBus“服务器”(提供要访问的对象)。通过你的总线名称到 Skype,注册一个名为 /com/Skype/Client 的对象路径,实现 com.Skype.API.Client 接口。
    2. 为此接口的唯一方法准备一个消息处理程序:Notify(s)。这是 Skype 将尝试调用的方法,以向您发送对您之前的请求之一的繁重回复。
    3. 编写您自己的机制,以将您的 Invoke 请求与稍后作为答案传入的异步 Notify 消息相匹配。

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

    • DBusConnection 结构代表您的总线名称。
    • 您要注册的对象路径,此处为/com/Skype/Client
    • 用于处理所有传入请求的消息处理程序 (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...
    }
    

    请注意,这只是一个对象的定义。为了真正hookNotify 调用,您必须在 DBusWatch 文件描述符上使用 select(),并调度传入的 DBusMessage 以便调用您的消息处理程序.

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 2022-07-11
      • 2014-05-29
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      相关资源
      最近更新 更多