PPAPI插件与浏览器的通信

时间:2024-10-10 17:45:19

PPAPI的插件,原本是可以使用JS与浏览器交互的,/p/ppapi/wiki/InterfacingWithJavaScript,这里还提供了一个JS与plugin交互的文档,但现在说不支持了,现在应该通过PPB_Messaging接口来完成Plugin和浏览器的交互,具体参考/viewvc/chrome/trunk/src/ppapi/c/ppb_messaging.h?revision=92312&view=markup这里。我实验了一下,通了。

Messaging接口很好,传递的消息可以自已定义,类型也无限制,非常方便。

foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。

使用postMessage通信

Messaging接口与其它大多数接口一样,分PPB和PPP两侧。分开来说明一下要做的事情。

插件侧

要做这么些事情:

  1. 实现PPP_Messaging接口,关键是void (*HandleMessage)(PP_Instance instance, struct PP_Var message)方法
  2. 在Get_Interface中返回名字是PPP_MESSAGING_INTERFACE的接口
  3. 在PPP_InitializeModule中获取 PPB_Messaging、PPB_Var、PPB_VarArray、PPB_VarDictionary等接口。
    PPB_Messaging的PostMessage用于向浏览器发送消息,发送过去的消息,JS代码可以接收到。
    PPB_Var可以用来构造String类型的Var,可以操作Var的引用计数
    PPB_VarArray是数组接口,可以创建、访问、设置数组
    PPB_VarDictionary是字典(map)接口,可以创建字典Var,可以存取key-value对。
  4. PPP_Messaging的HandleMessage处理浏览器的消息,如果需要,调用PPB_Messaging的PostMessage发送消息.

注意,插件侧调用PPB_Var接口的VarFromUtf8时,传入的len不包括’\0’在内。PPAPI的ppb_var.h的注释里的示例代码片段有误,调用时传递的长度是sizeof(hello_world),应该减去一。

还有一点,插件和浏览器交互的数据,都是数据的拷贝哦,调用接口会发生复制行为。

浏览器侧

浏览器侧可以使用JavaScript来监听插件发送的message事件,也可以使用插件元素的postMessage发送消息给插件。

基本上做下面几件事即可:

  1. 实现处理消息的JS函数,其参数是MessageEvent,data成员为插件发过来的信息,可以当做JS对象来访问。
  2. 监听插件的message事件
  3. 在合适的时候调用插件的postMessage(object)方法发送消息给插件

代码

分插件代码和HTML代码。

插件代码

代码是在在PPAPI插件中创建本地窗口一文示例代码的基础上改的,添加了消息处理的部分。只贴相关的部分了。

获取消息相关接口的代码

在PPP_InitializeModule中添加了获取PPB_Messaging接口以及其它可能用到的PP_Var类型的接口,有Array和Dictionary。

    g_var_interface = (const PPB_Var*)get_browser_interface(PPB_VAR_INTERFACE);
    g_dictionary_interface = (const PPB_VarDictionary*)get_browser_interface(PPB_VAR_DICTIONARY_INTERFACE);
    g_array_interface = (const PPB_VarArray*)get_browser_interface(PPB_VAR_ARRAY_INTERFACE);
    g_message_interface = (const PPB_Messaging*)get_browser_interface(PPB_MESSAGING_INTERFACE);

PPP_Messaging接口的实现

PPP_Messaging接口的实现代码如下:

void Plugin_HandleMessage(PP_Instance instance, struct PP_Var message)
{
    char szLog[256] = { 0 };
    sprintf_s(szLog, 256, "Plugin_HandleMessage, type = %d\r\n", );
    OutputDebugStringA(szLog);

    if ( == PP_VARTYPE_DICTIONARY)
    {
        char command[] = "command";
        struct PP_Var commandKey = g_var_interface->VarFromUtf8(command, sizeof(command) - 1);
        struct PP_Var commandVar = g_dictionary_interface->Get(message, commandKey);
        int len = 0;
        const char *strCommand = g_var_interface->VarToUtf8(commandVar, &len);
        g_var_interface->Release(commandKey);

        sprintf_s(szLog, 256, "Plugin_HandleMessage, dict, command = %s, len = %d\r\n", strCommand, len);
        OutputDebugStringA(szLog);

        if (len == 0)
        {
            OutputDebugString(_T("Tang_plugin, recv invalid command\r\n"));
            g_var_interface->Release(commandVar);
            return;
        }
        if (strncmp(strCommand, "joinConf", len) == 0)
        {
            char

相关文章