2009-12-19 1 views
8

Я пишу плагин веб-браузера (NPAPI.)Создание асинхронной Javascript событий из браузера плагин (NPAPI)

Мой плагин запускает рабочий поток, и как работник прогрессирует, я хотел бы передать события назад к Javascript. Но из-за модели Threading NPAPI, рабочий поток не является законным для прямого вызова в NPAPI, поэтому рабочий поток не может вызывать Javascript.

Одним из решений этого является функция NPN_PluginThreadAsyncCall. Но это относительно новая функция. Например, он поддерживается только с Firefox 3 on.

Есть ли способ получить доставку асинхронного события/выполнение javascript из плагина NPAPI без использования NPN_PluginThreadAsyncCall? Что люди делали до того, как эта функция была добавлена?

ответ

5

Ответ: да ... и нет ...

Если вам необходимо поддерживать старые браузеры (предварительно Firefox 3), вы можете реализовать NPN_PluginThreadAsyncCall функционировать самостоятельно. В окнах вы можете сделать это, создав структуру данных, которая может содержать указатель на функцию и указатель void * opaque, а затем отправлять специальное сообщение в главное окно с указателем на вашу структуру данных как LPARAM.

Главное окно WINPPROC работает в потоке пользовательского интерфейса, который является потоком, который может разговаривать с Javascript. Поэтому, когда вы получаете это сообщение в своем WINPROC, вы просто возвращаете LPARAM обратно в указатель, вызываете метод с непрозрачными данными и затем освобождаете структуру данных.

На Mac вы можете сделать аналогичную вещь с очередью для хранения событий, а затем в событии NULL (которое отправляется Mac OS о каждом тике), чтобы проверить, нет ли в нем чего-либо. Если это так, вытащите его, вызовите метод, освободите его и продолжайте.

Возможно, есть способ сделать это и на linux, но я не знаю, что это такое.

Вы можете найти пример версии окна в firebreath project.

Обработка сообщения WinProc в этом файле: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

события и структура данных определены в файле заголовок: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

И метод для стрельбы этого события здесь:

void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData) 
{ 
    if (m_hWnd != NULL) 
     ::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL, 
      (LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData)); 
} 
+1

Спасибо! Очень полезно знать, что поток цикла событий GUI платформы безопасен для вызовов NPAPI. И я обязательно проверю Firebreath. FWIW, на Mac, если вы можете зависеть от Cocoa, простой способ запустить код в потоке GUI - это метод NSObject выполняет функциюSelectorOnMainThread. – Geoff

+0

Да, я думаю, что кто-то рассказал мне о выполнении функцииSelectorOnMainThread, но мне не нужно было использовать его до сих пор. Процент пользователей, все еще находящихся на firefox 2, настолько мал в эти дни, что я просто решил больше не поддерживать его. С FireBreath мы могли бы добавить поддержку, если кому-то это было достаточно плохо (или они могли), но я не нуждаюсь в ней ни для кого из моих вещей. =] Есть несколько действительно приятных функций, которые не были реализованы до появления Firefox 2; Например, NPN_Enumerate и NPN_Construct. Кроме того, firefox 2 имеет известную ошибку, что он не видит плагинов, зарегистрированных в HKCU в окнах, поэтому вам нужно быть администратором. – taxilian