我在试图建立一个nsIProtocolHandler执行在德尔福。(我做了一个IInternetProtocol之前成功,并希望有FireFox什么我在互联网浏览器。) 谢谢来 d-壁虎 的项目,即以某种方式连接TInterfacedObject魔法的nsISupports魔法,我能够做出DLL,提供了一个nsIModule当要求,其中提供了一个nsIFactory当要求,其中提供了一个我nsIProtocolHandler的当要求,其中提供了一个我nsIChannel/nsIHttpChannel的当要求。

当试利用firefox.exe 作为东道主的过程中,我可以看看我的图书馆得到加载,NewURI被称为三次,NewChannel调,我通过一个对象实现和nsIChannel nsIHttpChannel.

这是我的困扰。我不应该呼叫OnStartRequest和OnDataAvailable在nsIStreamListener我得到的,直到我回来控制从AsyncOpen,但我似乎没有得到控制在线程,AsyncOpen被称为。

我已经试过调试用一个自制的包装默认http处理(经得到了与 CreateInstanceByContractID('@mozilla.org/network/protocol;1?name=http',...).我还裹的听众通过。奇怪的是,我看到OnStartRequest和OnDataAvailable得到所谓的 我的通道包装死了,在同一线。但是谁的电话?如果它是http道我想包装,它是如何生存下去(在同一线)以及它如何得到控制电话监听器?我百思不得其解。和坚持。

我试图联系的主要开发d-壁虎的项目,但没有得到响应。

(此外,有人曾经通知我的blurb在底部的 讨论页上MDC在nsIProtocolHandler?)

(哦还有一件事,是的,我知道"的生活会更简单的"如果我只是继承自nsBaseChannel在C++。但是添加一个火狐协议的处理程序的现有德尔斐项目的核心。)

更新: 我已经做了一些更多的阅读,它的提及 在这里, 为:"流听众的方法 所谓的在线电话asyncOpen[...]",但如何,可能没有被从所谓的'托管的应用'第一,不是我清楚。那是一个XPCOM伎俩?我想我已经读(很多)更多的火狐源之前,我得到它。

有帮助吗?

解决方案

我不知道Mozilla的编码的想法,但在这里不言而喻。

根据 nsIChannel :: asyncOpen()

  

异步打开该通道。数据   被供给到指定的流   听众变得可用。该   流听者的方法被称为   在调用asyncOpen和线程   不叫,直到asyncOpen后   回报。如果asyncOpen回报   成功,该通道承诺   调用至少onStartRequest和   onStopRequest。

因此,作为协议处理程序,需要实现一个通道对象是自己或重定向到一个通道对象,该通道的使用者调用您的频道上使用asyncOpen()。由于它是一个异步调用,这个想法是立即返回控制权交还给消费者,它是假设调用回调函数在加载数据。

我不知道如果我明白你的意思“但我似乎并没有得到控制回到线程AsyncOpen被称为”。线是用您的协议的消费者创建,并且它打开的通道。

另外,从 nsIChannel :: asyncOpen()

  

如果asyncOpen成功返回时,   信道是负责保持   本身的生命,直到它被称为   onStopRequest上aListener或者叫   onChannelRedirect。

由于asyncOpen返回控制权后面,通道本身需要保持本身活着的某个地方。

如果您正在寻找示例代码中,我发现codase是非常有用的。请参见 nsIProtocolHandler nsIChannel 。使用我碰到查看源代码协议 (这种实现可能是年纪大的,但并不重要)。

nsViewSourceHandler 实现自定义信道。

nsViewSourceHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
    nsresult rv;

    nsViewSourceChannel* channel;
    rv = nsViewSourceChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
    if (NS_FAILED(rv)) return rv;

    rv = channel->Init(uri);
    if (NS_FAILED(rv)) {
        NS_RELEASE(channel);
        return rv;
    }

    *result = NS_STATIC_CAST(nsIViewSourceChannel*, channel);
    return NS_OK;
}

这里的 nsViewSourceChannel 的AsyncOpen:

nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
    NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);

    mListener = aListener;

    /*
     * We want to add ourselves to the loadgroup before opening
     * mChannel, since we want to make sure we're in the loadgroup
     * when mChannel finishes and fires OnStopRequest()
     */

    nsCOMPtr<nsILoadGroup> loadGroup;
    mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
    if (loadGroup)
        loadGroup->AddRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
                                             this), nsnull);

    nsresult rv = mChannel->AsyncOpen(this, ctxt);

    if (NS_FAILED(rv) && loadGroup)
        loadGroup->RemoveRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
                                                this),
                                 nsnull, rv);

    if (NS_SUCCEEDED(rv)) {
        mOpened = PR_TRUE;
    }

    return rv;
}

无论如何,这是问,你是如何创建频道的一个漫长而曲折的道路?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top