博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PPAPI插件与浏览器的通信
阅读量:4621 次
发布时间:2019-06-09

本文共 8608 字,大约阅读时间需要 28 分钟。

PPAPI的插件,原本是能够使用JS与浏览器交互的,。这里还提供了一个JS与plugin交互的文档,但如今说不支持了。如今应该通过PPB_Messaging接口来完毕Plugin和浏览器的交互,详细參考这里。

我实验了一下。通了。

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代码。

插件代码

代码是在一文演示样例代码的基础上改的。加入了消息处理的部分。仅仅贴相关的部分了。

获取消息相关接口的代码

在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", message.type);    OutputDebugStringA(szLog);    if (message.type == 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 confIdKey[] = "confId";            char userNameKey[] = "userName";            char *szConfId = 0;            char*szUserName = 0;            struct PP_Var idKey = g_var_interface->VarFromUtf8(confIdKey, sizeof(confIdKey) - 1);            struct PP_Var userKey = g_var_interface->VarFromUtf8(userNameKey, sizeof(userNameKey) - 1);            struct PP_Var var = g_dictionary_interface->Get(message, idKey);            const char *value = g_var_interface->VarToUtf8(var, &len);            if (len > 0)            {                szConfId = malloc(len + 1);                strncpy_s(szConfId, len+1, value, len);                szConfId[len] = 0;            }            g_var_interface->Release(var);            var = g_dictionary_interface->Get(message, userKey);            value = g_var_interface->VarToUtf8(var, &len);            if (len > 0)            {                szUserName = malloc(len + 1);                strncpy_s(szUserName, len+1, value, len);                szUserName[len] = 0;            }            g_var_interface->Release(var);            sprintf_s(szLog, 256, "Plugin_HandleMessage, dict, command = joinConf, user = %s, confId = %s\r\n", szUserName, szConfId);            OutputDebugStringA(szLog);            if (szConfId && szUserName)            {                sprintf_s(szLog, 256, "plugin got confId - %s, user - %s\r\n", szConfId, szUserName);                OutputDebugStringA(szLog);                joinConf(szConfId, szUserName);            }            else            {                OutputDebugString(_T("Invalid conference id or userName\r\n"));            }            if (szConfId) free(szConfId);            if (szUserName) free(szUserName);            g_var_interface->Release(idKey);            g_var_interface->Release(userKey);            /* fake attendees*/            char szMsgTypeValue[] = "userlist";            char szTypeKey[] = "type";            struct PP_Var typeKey = g_var_interface->VarFromUtf8(szTypeKey, sizeof(szTypeKey) - 1);            struct PP_Var typeValue = g_var_interface->VarFromUtf8(szMsgTypeValue, sizeof(szMsgTypeValue) - 1);            struct PP_Var attendee = g_dictionary_interface->Create();            g_dictionary_interface->Set(attendee, typeKey, typeValue);            struct PP_Var userArray = g_array_interface->Create();            char szUser1[] = "ZhangSan";            char szUser2[] = "LiSi";            struct PP_Var user1 = g_var_interface->VarFromUtf8(szUser1, sizeof(szUser1) - 1);            struct PP_Var user2 = g_var_interface->VarFromUtf8(szUser2, sizeof(szUser2) - 1);            g_array_interface->Set(userArray, 0, user1);            g_array_interface->Set(userArray, 1, user2);            char szValueKey[] = "value";            struct PP_Var valueKey = g_var_interface->VarFromUtf8(szValueKey, sizeof(szValueKey) - 1);            g_dictionary_interface->Set(attendee, valueKey, userArray);            g_message_interface->PostMessage(instance, attendee);            OutputDebugString(_T("Post attendee to browser"));            g_var_interface->Release(typeKey);            g_var_interface->Release(typeValue);            g_var_interface->Release(user1);            g_var_interface->Release(user2);            g_var_interface->Release(valueKey);            g_var_interface->Release(userArray);            g_var_interface->Release(attendee);        }        else if (strncmp(strCommand, "viewVideo", len) == 0)        {            char userIdKey[] = "userId";            char *szUserId = 0;            struct PP_Var idKey = g_var_interface->VarFromUtf8(userIdKey, sizeof(userIdKey) - 1);            struct PP_Var var = g_dictionary_interface->Get(message, idKey);            const char *value = g_var_interface->VarToUtf8(var, &len);            if (len > 0)            {                szUserId = malloc(len + 1);                strncpy_s(szUserId, len + 1, value, len);                szUserId[len] = 0;            }            if (szUserId)            {                sprintf_s(szLog, 256, "plugin got userId - %s\r\n", szUserId);                OutputDebugStringA(szLog);                viewVideo(szUserId, g_child_window);            }            else            {                OutputDebugString(_T("Invalid viewVideo command without userId\r\n"));            }            if (szUserId) free(szUserId);            g_var_interface->Release(var);            g_var_interface->Release(idKey);        }        g_var_interface->Release(commandVar);    }    else if (message.type == PP_VARTYPE_STRING)    {        char hello_world[] = "Hello world!";        struct PP_Var var = g_var_interface->VarFromUtf8(hello_world, sizeof(hello_world) - 1);        g_message_interface->PostMessage(instance, var); // var will be copyed        g_var_interface->Release(var);    }}static PPP_Messaging message_interface = {    &Plugin_HandleMessage};

有点长,比較潦草。

返回PPP_Messaging的代码

完整的PPP_GetInterface函数例如以下:

PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {    if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)    {        OutputDebugString(_T("PPP_GetInterface, instance_interface\r\n"));        return &instance_interface;    }    else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)    {        OutputDebugString(_T("PPP_GetInterface, input_interface\r\n"));        return &input_interface;    }    else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0)    {        OutputDebugString(_T("PPP_GetInterface, message_interface\r\n"));        return &message_interface;    }    return NULL;}

网页代码

网页代码例如以下:

  
Tang in Plugin
ConferenceID:
  User:
  

contacts:

UserId:
  

share video:

Join按钮会获取它前面两个文本框的内容。发送给插件。插件返回一个用户列表,网页解析(HandleMessage方法)出来,动态改动用户列表。

执行效果

贴两幅图,点击Join按钮之前是酱紫的:

before

点击Join按钮后是酱紫的:

after


其他參考文章:

转载于:https://www.cnblogs.com/cxchanpin/p/7074450.html

你可能感兴趣的文章
提高生产性工具(四) - XML数据库的尝试
查看>>
ural 1005 Stone Pile DP
查看>>
day15—jQuery UI之widgets插件
查看>>
使用ssh和putty操控远程的linux server
查看>>
BZOJ1499: [NOI2005]瑰丽华尔兹
查看>>
1,悲剧的小学期
查看>>
从文本文件逐行读入数据
查看>>
Nios学习笔记2——流水灯实验
查看>>
过滤器
查看>>
Redis是什么?
查看>>
JavaScript 学习总结
查看>>
Android各版本及API对应关系,持续更新!
查看>>
复选框单选框与文字对齐问题的研究与解决
查看>>
关于苹果APP的上架整理
查看>>
Java continue的特殊用法 继续当前循环
查看>>
HDU 1988 Cube Stacking (数据结构-并查集)
查看>>
iOS开发——UI进阶篇(十)导航控制器、微博详情页、控制器的View的生命周期...
查看>>
爬虫篇
查看>>
多线程(四)线程生命周期和线程池
查看>>
fetch的用法
查看>>