Я понятия не имею о кодировании Mozilla, но здесь все сказано.
Согласно nsIChannel :: asyncOpen () ,
Асинхронно открыть этот канал. Данные
подается в указанный поток
слушатель по мере поступления.
методы слушателя потока вызываются
в потоке, который вызывает asyncOpen и
не вызывается, пока после asyncOpen
возвращается. Если asyncOpen возвращает
успешно канал обещает
вызвать хотя бы onStartRequest и
onStopRequest.
Таким образом, как протокольное средство, вы реализуете объект канала самостоятельно или перенаправляете его на объект канала, а потребитель канала вызывает ваш канал, используя asyncOpen()
. Поскольку это асинхронный вызов, идея состоит в том, чтобы немедленно вернуть элемент управления потребителю, и предполагается, что он вызывает обратные вызовы при загрузке данных.
Я не уверен, понимаю ли я, что вы подразумеваете под «но мне кажется, что я не могу получить контроль над тем потоком, в котором вызывался AsyncOpen» Поток создается потребителем вашего протокола и открывает канал.
Также из nsIChannel :: asyncOpen () :
Если asyncOpen успешно возвращается,
канал отвечает за хранение
сам жив, пока не вызвал
onStopRequest на aListener или вызывается
onChannelRedirect.
Поскольку asyncOpen возвращает элемент управления обратно, сам канал должен где-то поддерживать себя.
Если вы ищете пример кода, я нашел кодазу очень полезной. См. 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;
}
В любом случае, это долгий и извилистый способ спросить, как вы создаете свой канал?