2009-12-19 14 views
8

Tôi đang viết một plugin trình duyệt web (NPAPI.)Tạo async Javascript sự kiện từ plugin trình duyệt (NPAPI)

Plugin của tôi bắt đầu một sợi công nhân, và như người lao động đang diễn ra, tôi muốn vượt qua các sự kiện trở lại sang Javascript. Nhưng vì mô hình luồng NPAPI, nó không hợp pháp đối với chuỗi công nhân để gọi lại trực tiếp vào NPAPI, do đó, luồng công nhân không thể gọi Javascript.

Một giải pháp cho điều này là hàm NPN_PluginThreadAsyncCall. Nhưng đây là một chức năng tương đối mới. Ví dụ, nó chỉ được hỗ trợ từ Firefox 3 trở đi.

Có cách nào để nhận thực thi phân phối sự kiện/javascript không đồng bộ từ plugin NPAPI mà không sử dụng NPN_PluginThreadAsyncCall không? Mọi người đã làm gì trước khi chức năng này được thêm vào?

Trả lời

5

Câu trả lời là có ... và không ...

Nếu bạn cần hỗ trợ các trình duyệt cũ (trước firefox 3), bạn có thể thực hiện các chức năng NPN_PluginThreadAsyncCall mình. Trên cửa sổ, bạn có thể thực hiện điều đó bằng cách tạo cấu trúc dữ liệu có thể giữ con trỏ hàm và con trỏ mờ đục * và sau đó đăng thông báo tùy chỉnh lên cửa sổ chính với con trỏ tới cấu trúc dữ liệu của bạn như LPARAM.

Cửa sổ chính WINPPROC chạy trên luồng giao diện người dùng, là chuỗi có thể nói chuyện với Javascript. Vì vậy, khi bạn nhận được thông báo đó trong WINPROC, bạn chỉ cần đưa LPARAM trở lại con trỏ, gọi phương thức với dữ liệu mờ, và sau đó giải phóng cấu trúc dữ liệu.

Trên máy Mac, bạn có thể thực hiện một điều tương tự với hàng đợi để lưu trữ sự kiện, sau đó trên sự kiện NULL (được gửi bởi Mac OS về mọi dấu kiểm) để xem có bất kỳ thứ gì trong đó không. Nếu có, hãy tắt nó đi, gọi phương thức, giải phóng nó và tiếp tục.

Có lẽ cũng có cách để thực hiện trên linux, nhưng tôi không biết nó là gì.

Bạn có thể tìm thấy ví dụ về phiên bản cửa sổ trong số firebreath project.

Việc xử lý thông điệp winproc là trong tập tin này: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

Sự kiện và cấu trúc dữ liệu được định nghĩa trong tập tin tiêu đề của nó: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

Và phương pháp để bắn sự kiện đó là ở đây:

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

Cảm ơn bạn! Thật hữu ích khi biết rằng chuỗi sự kiện GUI nền tảng là an toàn cho các cuộc gọi NPAPI. Và tôi chắc chắn sẽ kiểm tra Firebreath. FWIW, trên Mac, nếu bạn có thể phụ thuộc vào Cocoa, một cách dễ dàng để chạy mã trên luồng GUI là phương thức NSObject performSelectorOnMainThread. – Geoff

+0

Vâng, tôi nghĩ ai đó đã nói với tôi về performSelectorOnMainThread, nhưng tôi không cần phải sử dụng nó cho đến nay. Tỷ lệ người dùng vẫn còn trên firefox 2 là quá nhỏ những ngày này mà tôi chỉ quyết định không hỗ trợ nó nữa. Với FireBreath, chúng tôi có thể thêm hỗ trợ nếu ai đó cần nó đủ mạnh (hoặc họ có thể), nhưng tôi không cần nó cho bất kỳ thứ gì của tôi. =] Có một số tính năng thực sự tốt đẹp mà không được thực hiện cho đến khi firefox 2; NPN_Enumerate và NPN_Construct, chẳng hạn. Ngoài ra, firefox 2 có một lỗi đã biết là nó không thể nhìn thấy các plugin được đăng ký trong HKCU trong các cửa sổ, vì vậy bạn phải là quản trị viên. – taxilian