P2P中间件SDK 开发手册
V 1.28.0
2017-05
深圳市穿透科技有限公司
介绍
1. 关于Peergine
Peergine是一个功能强大的对等通信中间件,用C/C++编程语言开发。为了适应多种运行环境,Peergine封装成了ActiveX控件、NPAPI插件、JNI插件和静态库等接口形式,支持Windows、Linux、Android、IOS和Mac OS X操作系统。可用C/C++、JavaScript、Java和Object-C编程语言构建各种设备端、客户端、浏览器端和服务器端的应用。
注:本编程手册以ActiveX控件(pgATX)的编程接口为例,说明Peergine中间件的使用方法。NPAPI插件、JNI插件、静态库的编程接口与ActiveX控件是兼容的。
2. Peergine的功能特性
1) 全新的网络编程模式
以面向对象的方法,把复杂的多点对等通信交互过程封装成通信对象,提供简单、直观的编程接口。即便是对网络通信知识缺乏了解的编程人员,也能够构建出功能强大的对等通信应用。参考“基于对象的多点通信会话”章节。
2) 强大的对等通信功能
以通信对象类的形式实现各种对等通信功能,目前支持的通信对象类为:
节点类:提供对象的两点通信范围控制。节点的登录/注销,两个节点之间的远程过程调用,两个节点之间的消息传输,数据签名的生成和校验。参考“使用节点类”章节。
通信组类:提供对象的多点通信范围控制。支持手动控制组成员、自动控制组成员和主(Master)成员控制功能。参考“使用通信组类”章节
消息传输类:多个节点之间单向传输消息。参考“使用消息传输类”章节。
文件传输类:两个节点之间的文件传输。支持PUT和GET传输方式,文件的断点续传。参考“使用文件传输类”章节
音频传输类:实时捕捉和传输音频。支持两点对话模式和多点会议模式。支持会议发言控制,实时音量变化显示,音频录制。参考“使用音频传输类”章节
视频传输类:实时捕捉和传输视频。支持本地预览模式、两点对话模式和多点会议模式。支持会议模式中视频的加入/离开,视频显示窗口的调整和转移,抓拍视频照片,视频录制。参考“使用视频传输类”章节。
白板共享类:多个节点共享白板,可设置绘制每种图形的参数,可设置绘制每种图形时的鼠标光标,保存白板内容到图片文件,从图片文件装入内容到白板。参考“使用白板共享类”章节。
文件分块共享类:类似BitTorrent和eMule,多个节点以分块的方式对等传输文件。顺序传输模式,分散传输模式,可设置文件传输的数据块大小,实时将获取到的文件数据转发到本地HTTP服务器上以便使用播放器或浏览器来播放文件。参考“使用文件分块共享类”章节。
数据表传输类:多个节点之间用访问数据库的方式传输数据。支持文件传输模式,每个文件对应到数据表的一条记录进行传输,实现文件的批量同步。参考“使用数据表传输类”章节。
媒体流直播类:多个节点之间对等直播媒体流。支持实时捕捉音频流、实时捕捉视频流和AVI文件播放的方式提供媒体源。支持媒体源的快速切换,丢帧重传,自动选择网络状况好的节点进行中继转发。支持媒体流录制。参考“使用媒体流直播类”章节。
3) 自适应的网络互通机制
以IPV4和IPV6的UDP协议为基础进行网络通信。对于UDP协议通信受限的节点,通过承载在TCP之上的隧道连接到中继服务器,然后转换成UDP协议通信。支持TCP、HTTP和WebSocket三种协议的隧道,以适应多种通信环境。通过中继服务器还可以完成 IPV4和IPV6之间的转换。支持位于IPV4私网中的节点的NAT穿越,自动探测NAT会话的老化时间,以恰当的时间间隔刷新NAT会话,防止老化。各种协议之间的转换互通,由Socket适配层自动适应,对上层通信对象透明。参考“配置和运行中继服务器”章节。
一个通信节点只占用一个UDP端口,并此端口上实现出多点通信机制,因此占用防火强或NAT的会话资源少。
支持HTTP代理方式通信,在代理后面的主机也能连接到Peergine网络。
实现QOS机制,每个节点都有4个优先级队列,分别对消息/信令、音频、视频和文件4种流量进行优先级调度,保证高优先级流量的服务质量。
支持对通信数据进行加密,加密的密钥自动协商生成,无需配置。
4) 控件提供丰富的辅助功能
Peergine在封装成控件时,又增加实现了辅助功能,包括常用的文件操作、文件缓冲区操作、本地Cookie存储、本地HTTP服务器、AVI文件播放等。这些辅助功能通过命令执行函数utilCmd()来调用。请参考“控件的命令列表”章节。
5) 多种OS平台和软件形态
Peergine封装成了ActiveX控件、NPAPI插件、JNI插件和静态库等接口形式,支持Windows、Linux、Android、IOS和MacOSX操作系统。可用C/C++、JavaScript、Java和Object-C编程语言构建各种设备端、客户端、浏览器端和服务器端的应用。
各种OS平台和软件形态的支持情况及路标如下表:
软件形态\OS | Windows | Linux | Android | Mac OS X | iOS |
ActiveX控件 | √ | — | — | — | — |
NPAPI插件 | √ | √ | — | — | — |
Java (JNI)插件 | √ | √ | √ | — | — |
静态库 | √ | √ | √ | √ | √ |
3. 基于对象的多点通信会话
1) 概念
在以往的网络编程方法中,例如,TCP连接、SIP会话等,通信会话一般指两点之间协商建立起来的通信交互。且也已经有了相应成熟的网络编程模型,例如Socket API。但在对等通信应用中,通信交互往往是多点对多点的,而且参与通信交互的节点会动态变化。如果依然使用两点通信的模型去搭建对等通信应用,那将是相当复杂、困难的事情,需要富有经验的网络编程人员才能完成。我们能否找到一种方法,让对等通信编程也变得直观、简单呢?其实,人们使用网络的行为可以简单表达为一句话:“多个人通过网络连接在一起做同一件事”。比如,多个人在一个聊天室里交谈、多个人在顶一个帖子、多个人在观看一个视频等等。我们可以把其中的“多个人”抽象为多个通信节点,“同一件事”抽象为一个通信会话,也就是把使用网络的行为抽象为一个“多点通信会话”。两点通信会话与多点通信会话的比较示意图,如下:
(a) 两点通信会话连接,(b) 多点通信会话连接
进一步,我们把一个多点通信会话封装成一个通信对象,用面向对象的方法来表述网络通信的特征,这样就使对等网络编程变得更加简单、直观。Peergine就是这种以通信对象为基础的对等通信系统。在系统中不同的通信业务类型表述为相对应的通信对象类,例如消息传输类、音频传输类、视频传输类等,而每一个通信对象实例表示一个通信会话。
2) 同名通信对象
Peergine系统中的一个通信对象通过一个名称来标识。每个通信节点有一个节点自身对象,其对象名称就是节点的名称,这个节点自身对象的名称必须是整个网络中唯一的。在每个通信节点上除了节点自身对象以外,还可以创建多个各种类型的通信对象,这些通信对象的名称必须在本节点范围内唯一。在不同的通信节点上就可以存在名称相同的通信对象,我们把这样的一套通信对象称为“同名通信对象”。在Peergine系统中,一套同名通信对象就是一个多点通信会话。位于不同节点上的相同名称的通信对象之间自动地建立起通信会话,然后在其中一个节点上调用该对象的方法,就可以完成与其它各节点之间的通信交互。同名通信对象建立通信会话的过程,称为“通信对象的同步”。
如下图,有NodeA、NodeB、NodeC三个节点,它们的自身对象分别为 NodeA、NodeB、NodeC。在节点NodeA可以创建一个节点对象NodeB与节点NodeB的自身对象同名,这时节点NodeA上的NodeB和节点NodeB的自身对象就是同名通信对象,它们之间自动建立会话连接。同样节点NodeA、NodeB、NodeC上都有通信组对象Group0和消息传输对象Data0,它们都组成相应的同名通信对象。
同名通信对象机制
3) 通信范围控制
当很多节点上都有名称相同的通信对象时,如何确定哪些节点上的同名通信对象才能组成一个多点通信会话呢?这就涉及到同名通信对象的通信范围问题。在Peergine系统中有两种可以用来确定通信范围的通信对象,它们分别是节点对象和通信组对象。对于节点对象,它的通信范围由对象名称决定。例如上图中,在节点NodeA上创建节点对象NodeB,它跟节点NodeB的自身对象同名,所以它的通信范围就是节点B。使用节点对象可以建立两点之间的通信会话。对于通信组对象,它的通信范围由它所包含的组成员决定。通信组对象的成员就是其通信范围内的节点的自身对象的名称。添加或删除通信组对象的成员可以改变通信组的通信范围。使用通信组对象可以建立多点之间的通信会话。对于其它业务类型的通信对象,例如消息传输对象、文件传输对象,它们没有控制通信范围的机制,则可以通过关联节点对象或通信组对象来控制通信范围。当它们关联节点对象时,实现两点之间的通信交互,当它们关联通信组对象时,实现多点之间的通信交互。一个节点对象或通信组对象可以被多个通信对象关联。参考“使用通信组类”章节。
4. 控件与应用程序的交互方式
1) 系统概述
Peergine中间件的系统框图如下,它位于应用程序和网络层的中间。上方通过控件提供的API与应用程序交互,下方通过OS的Socket API与网络协议栈交互。
系统框图
调用通信对象类的方法时,应用程序与pgATX控件之间的交互通过4个编程接口来完成。分别为发送请求ObjectRequest()、接收请求OnExtRequest()、发送应答ObjectExtReply()和接收应答OnReply(),其中OnExtRequest()和OnReply()是回调函数,需要在控件初始化时注册才能使用。但并不是所有的方法的调用都需要4个函数的交互过程,有些方法只需要其中1个或2个函数的交互。Peergine系统用到的交互方式由下文的小章节逐个说明。
2) 方式1:
本端应用程序发送请求、接收应答。对端应用程序接收请求、发送应答。
交互方式1
3) 方式2:
本端应用程序发送请求、接收应答。对端控件接收请求、发送应答。
交互方式2
4) 方式3:
本端控件发送请求、接收应答。对端应用程序接收请求、发送应答。
交互方式3
5) 方式4:
本端应用程序发送请求。对端应用程序接收请求。
交互方式4
6) 方式5:
本端应用程序发送请求,本端应用程序接收应答。
交互方式5
7) 方式6:
本端应用程序发送请求触发本端控件上报事件给应用。
交互方式6
8) 方式7:
本端应用程序调用本端控件的方法但没有输出。
交互方式7
9) 方式8:
本端控件自行上报事件给应用程序。
交互方式8
10) 方式9:
本端应用程序发送请求、接收应答。对端控件接收请求并在控件内部处理。
交互方式9
5. 常用的数据格式
1) 地址的格式
Peergine 系统中使用的地址格式为:X:X:X:X:Port:Info,其中4个X分别为32bit整数、HEX格式,Port为端口号,Info为选项信息(未使用)。此地址格式可以表示IPV4的地址端口和IPV6的地址端口。IPV4的地址端口样例:0:0:0:7F000001:80:0或0:0:0:127.0.0.1:80:0。IPV6的地址端口样例:FE800000:0:01B05996:42CFB70D:80:0。
IPV4和IPV6地址格式到Peergine地址格式的对应关系如下图:
IPV4地址到Peergine地址的对应关系
IPV6地址到Peergine地址的对应关系
2) 时间的格式
Peergine系统中使用的时间格式为:YYYY-MM-DD,HH:MM:SS。样例:2011-10-22,18:20:09。
3) 文件摘要的格式
Peergine 系统中使用的文件摘要格式为:SHA256算法生成,Base64编码。
4) 视频窗口的参数格式
Peergine 系统中使用的视频窗口参数格式为:(PosX){0}(PosY){0}(SizeX){80}(SizeY){60}(Handle) {343454}。其中,PosX和PosY为视频左上角在窗口中的坐标,SizeX和 SizeY为视频的尺寸,Handle为窗口的句柄。
SDK的安装使用说明
1. Windows平台:
ActiveX控件:可执行文件为pgATX.ocx,使用regsvr32命令注册后就可以在浏览器和WSH中调用Peergine的API。
NPAPI插件:可执行文件为nppgnpp.dll,复制到Chrome、Firefox和Safari的plugins目录后就可以在浏览器中调用Peergine的API。
JNI插件:可执行文件为pgJNI.dll,将其路径添加到PATH环境变量中。
JNI类库:pgJNILib.jar包文件,包含了pgJNI、pgJNINode和pgJNINodeProc共3个java类。将其路径添加到CLASSPATH环境变量中,就可以在Java应用程序中调用Peergine的API。
2. Linux平台:
NPAPI插件:可执行文件为libpgnpp-plugin.so,复制到/usr/lib/mozilla/plugins目录后就可以在浏览器中调用Peergine的API。
JNI插件:可执行文件为libpgJNI.so,将其路径添加到PATH环境变量中。
JNI类库:pgJNILib.jar包文件,包含了pgJNI、pgJNINode和pgJNINodeProc共3个java类。将其路径添加到CLASSPATH环境变量中,就可以在Java应用程序中调用Peergine的API。
3. Android平台:
安装包:peergine_clt_android.apk,包含了NPAPI插件和JNI插件的可执行文件,直接执行安装之后可以使用。
JNI类库:提供了pgLibJNINode.java和pgLibJNINodeProc.java两个类的源代码,可以直接添加到应用的代码工程中就可以调用Peergine的API。
配置和运行中继服务器
1. 关于
Peergine使用UDP协议进行通信(如下图)。
直接UDP通信方式
但在实际网络环境中,某些节点的UDP通信是受限的。例如,这些节点位于防火墙的后面,而防火墙把UDP端口全部封锁。庆幸的是防火墙不会封锁所有网络的访问权限,一般来说防火墙会保留对Web的访问。Web应用通常使用HTTP(80端口)和HTTPS(443端口)协议通信,这两种协议都基于TCP协议。依此,Peergine提供了一个中继服务器程序,在TCP协议之上实现TCP、HTTP和WebSocket三种协议的隧道功能(如下图)。UDP通信受限的节点能通过隧道连接到中继服务器,然后转换成UDP通信再跟其他节点互通。(注:WebSocket的二进制传输标准W3C还没有制订完成,所以该协议的隧道还没有实现)
通过TCP隧道中继转成UDP通信方式
IPV4网络的地址已经耗尽了,IP网络正处于IPV4到IPV6的过渡过程中,所以这两种协议在网络中是共存的。但IPV4和IPV6是不兼容的,它们之间需要某种机制进行转换后才能互通。Peergine中继服务器提供了IPV4和IPV6的转换功能,使IPV4节点与IPV6节点之间也能互通。
2. 配置运行
Peergine中继服务器的可执行文件为pgRelay.exe,缺省的配置文件为pgRelay.cfg。缺省配置文件必须放在与pgRelay.exe相同的目录下。配置文件是一个OML格式的文本文件,可以使用文本编辑器打开编辑。如果使用其他配置文件,可以通过pgRelay.exe的命令行参数指定其他配置文件的路径。例如,在命令行提示符下执行:c:>pgRelay.exe “c:\Peergine\bin\pgRelay1.cfg”。
中继服务器的配置文件的结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
(MaxThread){16} //最大的转发线程数目(每个线程最多允许32条TCP连接)。 (ListenList){ //侦听端口列表,可以配置最多32个侦听端口。 (Name1){ //侦听端口1 (Type){0} //隧道类型:TCP隧道 (AddrListen){FE800000:0:01B05996:42CFB70D:7777:0} //TCP侦听地址/端口(这是个IPV6地址) (AddrUDP4){0:0:0:127.0.0.1:0:0} //转换成UDP后的IPV4地址,端口自动分配。 (AddrUDP6){FE800000:0:01B05996:42CFB70D:0:0} //转换成UDP后的IPV6地址,端口自动分配。 } (Name2){ //侦听端口2 (Type){1} //隧道类型:HTTP隧道 (AddrListen){0:0:0:127.0.0.1:8888:0} //TCP侦听地址/端口(这是个IPV4地址) (AddrUDP4){0:0:0:127.0.0.1:0:0} //转换成UDP后的IPV4地址,端口自动分配。 (AddrUDP6){FE800000:0:01B05996:42CFB70D:0:0} //转换成UDP后的IPV6地址,端口自动分配。 } } (Node){ // 登录到集群服务器的参数,用来搭建中继服务器的集群功能(未实现)。 (SvrName){PGServer} (SvrAddr){0:0:0:127.0.0.1:1112:0} (CltAddr){0:0:0:127.0.0.1:1118:0} (User){pgRelay1} (Pass){} (RefPeer){} } |
Peergine中继服务器应该部署在具有公网IP地址且所有节点都能到达的网络主机上。如果要使用IPV4和IPV6的转换功能,该网络主机必须具备IPV4和IPV6双栈,且IPV4和IPV6网络都能到达。
如何使用pgATX控件编程
1. 使用控件的编程接口
1) 初始化控件
有两种方式创建pgATX控件的实例:HTML的<object>标签和JavaScript的ActiveXObject()函数。
控件运行在浏览器中时,建议用HTML的<object>标签创建,这种方式不仅可以使用控件的所有功能,还可以使用控件的窗口来显示视频和白板。代码示例(HTML):
1 |
<object id="pgAtx" classid="clsid:FFC9369F-A8D9-4598-8E22-ED07C7628BFC" width="320" height="240"></object> |
控件运行在Windows Script Host中时,使用JavaScript的ActiveXObject()函数创建,代码示例(JavaScript):
1 |
var pgAtx = new ActiveXObject("pgATX.pgATXCtrl"); |
创建控件实例后,通过给控件的配置属性变量赋值进行配置,然后调用Start()函数启动控件的节点功能。代码示例(JavaScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
pgAtx.Control = "Type=1"; pgAtx.Node = "Type=0"; pgAtx.Class = "PG_CLASS_Data:8;PG_CLASS_File:64;PG_CLASS_Audio:8;PG_CLASS_Video:8"; pgAtx.Local = "Addr=0:0:0:127.0.0.1:0:0"; pgAtx.Server = "Name=PGServer;Addr=0:0:0:127.0.0.1:1112:0"; pgAtx.Relay = "(Relay0){(Type){1}(Load){0}(Addr){FE800000:0:01B05996:42CFB70D:7777:0}}"; pgAtx.OnExtRequest = pgOnExtRequest; pgAtx.OnReply = pgOnReply; if (!pgAtx.Start(0)) { alert("Initialize failed"); } |
请参考“控件的属性配置项”章节。
2) 使用通信对象
初始化控件实例之后,就可以使用控件的节点功能函数。
用ObjectAdd()函数创建通信对象,用ObjectDelete()删除通信对象。用ObjectSetGroup()函数设置或修改通信对象的关联通信组。虽然在ObjectAdd()函数中已经指定了通信对象的关联通信组,但可以使用此函数进行修改。如果指定的通信组参数为空,则取消与通信组关联。
通信对象在创建之后或用ObjectSetGroup()修改关联通信组之后会自动与通信范围内的其他节点上的同名通信对象进行同步。但由于网络不稳定或者通信对象创建的先后顺序等因素,会导致同步失败。这时可以使用ObjectSync()函数主动触发通信对象进行同步。
通信对象同步以后,就可以调用通信对象的方法。需要ObjectRequest()、ObjectExtReply()、OnExtRequest()和OnReply()这4 个函数配合才可以完成一次方法的调用。其中OnExtRequest()和OnReply()是回调函数,需要在控件初始化时注册,请参考“控件的属性配置项”章节。首先请求端节点的应用程序调用控件的ObjectRequest()函数发起请求,控件通过网络交互发送请求数据到接收端节点,接收端节点的控件回调OnExtRequest()函数上报请求给应用程序。应用程序处理完请求后调用控件的ObjectExtReply()函数发送应答,控件通过网络交互发送应答数据给请求端节点,请求端节点的控件回调OnReply()函数上报应答给应用程序。这样就完成了一次方法的调用。参考“pgATX控件与应用程序的交互方式”章节和“简单聊天室例子”章节。
3) 处理消息循环
控件与应用程序的交互过程需要通过系统的消息队列投递消息。当控件运行在界面线程中 (例如运行在浏览器中)时,界面线程能够处理消息循环。但运行在Windows Script Host中时,线程没有消息循环,无法完成交互消息的投递。这时就需要应用程序调用控件的PumpMessage()函数主动处理消息队列。代码示例(JavaScript):
1 2 3 4 5 |
while (pgAtx.PumpMessage(0)) { // DO TO } |
4) 使用OML解析器
调用控件的通信对象的方法时,输入、输出的参数都是OML格式。控件提供了一组OML解析器函数来辅助构造和解析OML字符串。请参考“控件的OML解析器函数”和“对象标记语言(OML)”章节。OML解析器的每个函数都是无状态的,函数之间也没有关联。函数的每一次调用都是独立的,调用完成后通过返回值输出处理后的OML字符串。
5) 获取控件的窗口参数
控件运行在浏览器中时,一个重要用途是做为视频显示和白板共享的窗口。控件提供了辅助函数utilGetWndRect()来获取控件窗口的尺寸和句柄,以便用来初始化视频或白板窗口。
6) 使用控件的辅助命令
在构建应用程序的过程中,除了网络通信外,还需要调用操作系统的某些资源或功能才能构成完整的应用程序。控件提供了一些常用的辅助功能,例如,常用文件操作、文件缓冲区操作、本地HTTP服务器控制和AVI文件播放等。通过辅助函数utilCmd()来调用这些辅助功能。请参考“控件的命令列表”章节。
7) 使用安全沙盒目录
Peergine是一个对等通信中间件,不可避免地要访问本地的文件系统。比如,发送接收文件、缓存文件等。为了防止某些恶意的应用程序使用Peergine进行偷窃用户数据、传输恶意代码等不良操作,Peergine通过使用沙盒目录来控制文件系统的访问范围。控制规则如下:
(1) 所有涉及到网络传输的文件访问都限制在沙盒目录内。
(2) 本地的文件操作,可以访问沙盒目录之外的文件。比如,拍摄照片保存到本地文件,装载本地图片到白板中。
在下文各个功能的编程参考章节中,涉及访问文件系统时,将会逐个说明是否受到沙盒目录限制。缺省情况下,沙盒目录是当前用户的“Documents”目录下的“Peergine”目录。可以通过控件的右键菜单或Setting()命令弹出设置对话框,让用户修改沙盒目录的父目录位置。
注:沙盒目录必须具有:创建、删除、写、读等文件操作的权限,否则Peergine的某些功能将失效。
沙盒目录中的文件的移入和移出通过FileCopy()命令完成,FileCopy()的Src参数和Dst参数的使用规则如下:
(1) Src和Dst都指定了文件路径(非空),则Src和Dst指定的文件都必须在沙盒目录内,否则命令调用执行失败。
(2) Src指定了文件路径且Dst为空,则Src指定的文件必须在沙盒目录内。当命令执行时,Peergine弹出文件对话框,让用户选择Dst文件路径,进行文件移出操作。
(3) Src为空且Dst指定了文件路径,则Dst指定的文件必须在沙盒目录内。当命令执行时,Peergine弹出文件对话框,让用户选择Src文件路径,进行文件移入操作。
注:如果使用Peergine之外的途径移入/移出文件,则 Peergine将无法保证其安全性。比如,使用控制台copy命令复制文件,在资源管理器里手工复制、粘贴文件,或者调用操作系统API复制文件等。
2. 使用节点类(PG_CLASS_Peer)
1) 创建节点对象
动态节点对象:创建节点对象时不带任何选项,所创建的就是一个动态节点对象。在通信组对象添加成员时,如果该成员所对应的节点对象不存在,则系统自动创建一个对应的动态节点对象。所以,动态节点对象一般都由系统自动创建,无须直接调用控件的API创建。请参考“使用通信组类”章节。动态节点对象创建后,系统使用PG_METH_PEER_Status方法从登录服务器获取该节点的地址,并配置该动态节点对象的网络资源。
静态节点对象:创建静态节点对象使用PG_ADD_PEER_Static选项。静态节点对象不会从登录服务器获取地址,需要调用PG_METH_PEER_SetAddr方法来设置地址。
登录服务器节点对象:创建登录服务器节点对象使用PG_ADD_PEER_Server选项。在一个节点上只能有一个登录服务器节点对象,如果创建第二个,则前面一个自动销毁。在实际使用中不需要直接创建登录服务器节点对象,而是在控件初始化时,由系统自动创建。代码示例(JavaScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
pgAtx.Control = "Type=1"; pgAtx.Node = "Type=0"; // 作为普通节点 pgAtx.Class = "PG_CLASS_Data:8;PG_CLASS_File:64;PG_CLASS_Audio:8;PG_CLASS_Video:8"; pgAtx.Local = "Addr=0:0:0:127.0.0.1:0:0"; // Name参数指定登录服务器节点对象的名称,Addr参数指定登录服务器节点的地址。 pgAtx.Server = "Name=PGServer;Addr=0:0:0:127.0.0.1:1112:0"; pgAtx.Relay = "(Relay0){(Type){1}(Load){0}(Addr){FE800000:0:01B05996:42CFB70D:7777:0}}"; pgAtx.OnExtRequest = pgOnExtRequest; pgAtx.OnReply = pgOnReply; pgAtx.Start(0); |
节点自身对象:创建登录服务器节点对象使用PG_ADD_PEER_Self选项。在一个节点上只能有一个节点自身对象,如果创建第二个,则前面一个自动销毁。在实际使用中不需要直接创建节点自身对象,而是在控件初始化或调用登录方法时,有系统自动创建。
节点作为登录服务器节点(服务器端)时,在控件初始化时创建节点自身对象,代码示例(JavaScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
pgAtx.Control = “Type=1”; pgAtx.Node = “Type=1”; // 作为登录服务器节点 // Name参数指定节点自身对象的名称,Addr参数指定节点的地址。 pgAtx.Local = “Name= PGServer;Addr=0:0:0:127.0.0.1:1112:0”; pgAtx.OnExtRequest = pgOnExtRequest; pgAtx.OnReply = pgOnReply; pgAtx.Start(0); |
节点作为普通节点(客户端)时,在调用登录方法时创建节点自身对象,代码示例(JavaScript):
// User参数指定节点自身对象的名称,节点的地址由系统自动分配。
var sData = “(User){UserName000}(Pass){}(Param){}”;
var uErr = pgAtx.ObjectRequest(“PGServer”, 32, Data, “Login”);
2) 简单的两点直接通信
为了便于开始理解节点对象,我们编写一个两点直接通信的程序。代码示例(JavaScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<object id="pgAtx" classid="clsid:FFC9369F-A8D9-4598-8E22-ED07C7628BFC" width="0" height="0"></object> <script language="javascript"> // 初始化控件实例。 pgAtx.Control = “Type=1”; pgAtx.Node = “Type=1”; pgAtx.Local = “Name=” + sLocalName + “;Addr=” + sLocalAddr; pgAtx.OnExtRequest = pgOnExtRequest; pgAtx.OnReply = pgOnReply; pgAtx.Start(0); // 创建对端节点对象,并设置地址。 pgAtx.ObjectAdd(sRemoteName, “PG_CLASS_Peer”, “”, 0x4); var sInEle = “(Addr){“ + sRemoteAddr + “}(Proxy){}”; pgAtx.ObjectRequest(sRemoteName, 37, sInEle, “SetAddr”); // 给对端节点发送消息“Hello!”。 pgAtx.ObjectRequest(sRemoteName, 36, “Hello!”, “SendMsg”); // 回调函数。 function pgOnExtRequest(sObj, uMeth, sData, uHandle, sPeer) { if (sObj == sLocalName && uMeth == 36) { alert(sData); // 显示接收到的“Hello!”消息 } } function pgOnReply(sObj, uErr, sData, sParam) { } </script> |
但是,这个程序在实际中很难使用,因为要事先知道对端节点的网络地址。对此,Peergine提供了自动交换节点网络地址的方法,请看参考下文的“登录、注销和地址解析”章节。
3) 登录、注销和地址解析
在Peergine系统中,通信节点是用节点对象的名称来标识的,但在通信过程中需要根据节点的网络地址来传输报文。所以,需要一种机制把节点对象名称转换成节点的网络地址(也称为地址解析)。Peergine提供了一种特殊的通信节点(登录服务器节点),用来完成地址解析功能。在控件初始化时,把Node配置项的Type参数赋值为1,则该节点就是登录服务器节点。登录服务器节点比普通节点增加了以下几点功能:
(1) 接受其他普通节点的登录、验证账号和记录登录状态。
(2) 处理其他普通节点的地址解析请求,返回指定节点的地址信息和登录状态。
(3) 协助普通节点处理NAT穿越和中继隧道类型的协商。
普通节点通过调用登录服务器节点对象的PG_METH_PEER_Login和PG_METH_PEER_Logout方法来请求登录和注销。当在普通节点上创建了一个新的节点对象时,控件会自行调用登录服务器节点对象的PG_METH_PEER_Status方法来解析该节点的地址信息和登录状态。如果解析返回该节点已经登录,则与该节点建立通信会话。
注:PG_METH_PEER_Login和PG_METH_PEER_Logout方法只能在登录服务器节点对象上调用,在其他节点对象上调用这两个方法将返回失败。
4) 远程过程调用
调用节点类的PG_METH_PEER_Call方法可进行两个节点之间的远程过程调用,该方法的请求参数和应答参数的内容由应用程序定义,控件透明传输。
5) 两点消息传输
调用节点类的PG_METH_PEER_Message方法可进行两个节点之间的单向消息传输。该方法的请求参数的内容由应用程序定义,控件透明传输。
6) 数据的签名和校验
调用节点类的PG_METH_PEER_DigGen方法产生数据的签名,调用节点类的PG_METH_PEER_DigVerify方法校验数据的签名。
7) 异常离线(掉线)的判断
普通节点登录到服务器几点上后,由于网络中断、服务器关闭重启等,都会导致异常离线,也就是常说的掉线。在普通节点上需要及时判断异常离线,并尝试重新登录上线。原则上讲,普通节点与服务器节点之间通信时,如果中断或者访问超时,则说明异常离线了。下面以一段伪码说明如何判断异常离线:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
// 假设服务器节点的节点名为: var sObjSvr = “PGServer”; // 假设需要登录的普通节点的节点名为: var sObSelf = “123@peergine.com”; // 在OnExtRequest 回调函数中 function OnExtRequest(sObj, uMeth, sData, uHandle, sPeer) { // 自身节点与服务器节点之间的去同步事件 if (sObj == sObSelf) { if (uMeth == 0) { // PG_METH_COMMON_Sync=0方法 var sAct = pgAtx.omlGetContent(sData, "Action"); if (sAct != "1" && sPeer == sObjSvr) { // 异常离线了。如果设置了自动重新登录选项,则无需处理。 } } } // 服务器节点事件 if (sObj == sObjSvr) { if (uMeth == 0) { // PG_METH_COMMON_Sync=0方法 var sAct = pgAtx.omlGetContent(sData, "Action"); if (sAct != "1") { // 服务器节点的去同步事件 // 异常离线了。如果设置了自动重新登录选项,则无需处理。 } } else if (uMeth == 1) { // PG_METH_COMMON_Error=1方法 var sMeth = pgAtx.omlGetContent(sData, "Meth"); if (sMeth && parseInt(sMeth) == 32) { // PG_METH_PEER_Login= 32方法 // 服务器节点的登录方法,上报错误事件 // 异常离线了。如果设置了自动重新登录选项,则无需处理。 } } return 0; } } // 在OnReply 回调函数中 function OnReply(sObj, uErr, sData, sParam) { // 访问服务器节点时返回 PG_ERR_Network=11和PG_ERR_Timeout=12错误码。 if (sObj == sObjSvr) { if (uErr == 11 || uErr == 12) { // 登录失败。 // 需要调用PG_METH_PEER_Logout注销,然后再调用PG_METH_PEER_Login登录。 } } } |
3. 使用通信组类(PG_CLASS_Group)
1) 手动控制成员
通过调用通信组类的PG_METH_GROUP_Modify方法来手动添加、删除通信组的成员,必须启用PG_ADD_GROUP_Modify选项后才允许调用该方法。通信组对象添加成员后,该通信组对象会与其成员所对应的节点上的同名通信组对象建立同步,其成员列表也会复制到与其成员所对应的节点上的同名通信组对象。
举例说明:有NodeA、NodeB和NodeC三个节点,它们都有通信组对象Group0,开始Group0的成员列表都是空的。在节点NodeA上给Group0添加成员“NodeA”、“NodeB”和“NodeC”,则节点NodeA上的Group0会与节点NodeB和NodeC上的Group0建立同步,同时节点NodeA上的Group0的成员列表也复制到节点NodeB和NodeC上的Group0,使节点NodeB和NodeC上的Group0都包含成员“NodeA”、“NodeB”和“NodeC”。当然节点NodeB和NodeC上的Group0都包含了对方节点作为成员后,它们之间也会建立同步。
注:给通信组对象添加一个成员后,如果该成员名称所对应的节点对象还不存在,则系统会自动创建该节点对象。
2) 自动控制成员
Peergine还提供了一种自动控制通信组对象的成员的方法:
(1) 当一个通信组对象启用了PG_ADD_GROUP_Refered选项时,则允许其他同名通信组对象引用该通信组对象的成员,它的成员列表将自动复制到引用它的同名通信组对象。当它的成员发生变化时,会实时地通知给引用它的同名通信组对象。
(2) 一个通信组对象引用了另一个通信组对象的成员时,它自身的节点也同时加入了被引用的通信组对象的成员列表。当它取消了引用或被删除时,它自身的节点就离开了被引用的通信组对象的成员列表。
举例说明:有NodeA、NodeB和NodeC三个节点,它们都有通信组对象Group0,开始Group0的成员列表都是空的,其中节点NodeA启用了PG_ADD_GROUP_Refered选项。节点NodeB和NodeC上的Group0在创建时指定关联了节点NodeA,那么节点NodeB和NodeC就加入了节点NodeA上的Group0的成员列表,同时节点NodeA上的Group0的成员列表也复制到节点NodeB和NodeC上的Group0。如果节点NodeB上的Group0取消关联节点NodeA或被删除,则节点NodeB就离开了节点NodeA上的Group0的成员列表,同时节点NodeA上的Group0会通知节点NodeC上的Group0把节点NodeB从其成员列表中删除。
代码示例(JavaScript):
// 在节点NodeA上创建Group0,选项为PG_ADD_GROUP_Refered=0x4
pgAtx.ObjectAdd(“Group0”, “PG_CLASS_Group”, “”, 0x04);
// 在节点NodeB和NodeC上创建Group0,关联节点NodeA。
pgAtx.ObjectAdd(“Group0”, “PG_CLASS_Group”, “NodeA”, 0);
3) 邻近成员控制
在对等通信场景中,有时候一个通信组内的成员会很多,但一个节点只希望与离它最近的几个节点交互。Peergine针对这种情况提供了一种邻近节点控制的功能。一个通信组对象启用了PG_ADD_GROUP_Refered选项作为成员引用对象,如果同时启用了PG_ADD_GROUP_NearPeer选项,则它就使能了邻近节点控制功能。使能了邻近节点控制功能通信组对象只把在邻近范围内的成员复制到引用它的通信组对象。邻近范围的大小缺省为6,可以通过PG_METH_COMMON_SetOption方法的修改。
举例说明:节点NodeA上的Group0已经包含了很多成员,节点NodeB和NodeC是其中的两个成员。那么,节点NodeA上的Group0给节点NodeB上的Group0复制了离节点NodeB最近的6个成员。同样,节点NodeA上的Group0给节点NodeC上的Group0复制了离节点NodeC最近的6个成员。以此类推,每个成员节点上的Group0都复制到了离该节点最近的6个成员。
4) 主成员控制
在某些应用场景中,一个通信组中需要有一个权限更高的成员来管理其他成员。Peergine针对这种情况提供了一种主成员控制功能。通信组对象启用了PG_ADD_GROUP_Master选项后才可以使用主成员控制功能。通过调用PG_METH_GROUP_Master方法向通信组内的成员公告主成员的名称,成员接收到公告后,通过返回应答的错误码确认是否接受该主成员公告。
4. 使用消息传输类(PG_CLASS_Data)
1) 多点消息传输
节点类提供两点之间消息传输功能。消息传输类提供多点之间的消息传输功能。调用PG_METH_DATA_Message方法可以给所关联的通信组成员的发送单向的消息,消息的内容完全由应用程序决定,控件透明传输。参考“PG_CLASS_Data类”章节
5. 使用文件传输类(PG_CLASS_File)
1) 两点文件传输
文件传输类提供了两点之间传输文件的功能。方法PG_METH_FILE_Put和PG_METH_FILE_Get分别为上传和下传文件。方法PG_METH_FILE_Cancel中断一个正在进行的文件传输。方法PG_METH_FILE_Status上报文件传输的状态。开始传输时,可以通过Offset和Size参数指定只传输文件的一个片段。进行多次传输不同的片段可以组成一个断点续传的过程。参考“PG_CLASS_File类”章节。
6. 使用音频传输类(PG_CLASS_Audio)
1) 两点模式
音频传输类有两种模式:两点模式和会议模式,缺省为两点模式。两点模式允许经过呼叫协商之后才建立通话,一端发起请求之后,另一端可以选择接受或拒绝,只有对端选择接受后通话才建立。发起端调用PG_METH_AUDIO_Open方法发起呼叫请求,对端接收到呼叫请求后,通过返回应答的错误码来确认接受或拒绝,错误码等于0表示接受,错误码大于0表示拒绝及其原因。
两点模式时,如果音频传输对象关联的通信组对象有多个成员,则系统选择第1个成员作为对端节点。所以,为了使通信范围更加准确,建议音频传输对象关联节点对象作为对端节点,或者关联的通信组对象始终保持只有1个成员作为对端节点。
2) 会议模式及发言控制
通过PG_ADD_AUDIO_Conference选项开启会议模式。会议模式下不需要呼叫过程,调用 PG_METH_AUDIO_Open方法打开对象之后就直接加入到会议中,可以跟通信组内的所有节点通话。会议模式下可以调用PG_METH_AUDIO_Speech方法来控制指定节点的发言状态。
3) 设置和获取音量
调用PG_METH_AUDIO_CtrlVolume方法可设置和获取麦克风和扬声器的音量。
4) 实时显示音量的变化
启用了PG_ADD_AUDIO_ShowVolume选项后,系统会调用PG_METH_AUDIO_ShowVolume方法上报在麦克风输入和扬声器输出的音频信号的音量。上报的频率为200毫秒1次,静音不会上报。应用程序可以依此在图像界面上显示输入/输出音量的变化。
5) 音频录制
调用PG_METH_AUDIO_Record方法可将音频输出录制到由Path参数指定的AVI文件中。如果调用时指定Path参数为空,则停止当前正在进行的录制操作。
如果想将音频和视频录制到同一个AVI文件中,则在开始录制音频和视频时,都给Path参数指定同一个AVI文件。请参考“视频录制”章节。
7. 使用视频传输类(PG_CLASS_Video)
1) 预览模式
视频传输类有三种模式:预览模式、两点模式和会议模式。预览模式用PG_ADD_VIDEO_Preview选项开启,用来显示从本地视频捕捉设备上输入的视频图像。
2) 两点模式
缺省为两点模式。两点模式允许经过呼叫协商之后才建立通话。一端发起请求之后,另一端可以选择接受或拒绝,只有对端选择接受后通话才建立。发起端调用PG_METH_VIDEO_Open方法发起呼叫请求,对端接收到呼叫请求后,通过返回应答的错误码来确认接受或拒绝,错误码等于0表示接受,错误码大于0表示拒绝及其原因。
两点模式时,如果视频传输对象关联的通信组对象有多个成员,则系统选择第1个成员作为对端节点。所以,为了使通信范围更加准确,建议视频传输对象关联节点对象作为对端节点,或者关联的通信组对象始终保持只有1个成员作为对端节点。
3) 会议模式及视频的加入和离开
会议模式用PG_ADD_VIDEO_Conference选项开启。调用PG_METH_VIDEO_Open打开视频会议后,缺省没有视频通话加进来,需要PG_METH_VIDEO_Join和PG_METH_VIDEO_Leave使视频加入或离开。视频加入需要经过呼叫协商,对端选择接受之后,视频才能加入到会议中。
4) 视频窗口调整和转移
调用PG_METH_VIDEO_Move方法可以调整视频在窗口中显示的位置和尺寸,或者从当前的窗口转移到另一个窗口中。调用此方法时,如果只是改变了参数中的坐标参数,则调整视频在窗口中的显示位置和尺寸。如果改变了窗口的句柄,则把视频转移到另一个窗口中显示。
5) 拍照片
调用PG_METH_VIDEO_Camera方法对输出的视频拍照片。Path参数指定保存照片的文件路径,照片文件必须是“.jpg”文件。
6) 视频录制
调用PG_METH_VIDEO_Record方法可将视频输出录制到由Path参数指定的AVI文件中。如果调用时指定Path参数为空,则停止当前正在进行的录制操作。
如果想将视频和音频录制到同一个AVI文件中,则在开始录制视频和音频时,都给Path参数指定同一个AVI文件。请参考“音频录制”章节。
8. 使用白板共享类(PG_CLASS_Board)
1) 设置绘制图形的参数
调用PG_METH_BOARD_Shape方法可设置绘图的参数,包括图案类型、线条宽度、线条颜色和线条样式。在一个节点上绘图时,通信组内的其他节点上会实时显示。
2) 设置绘制不同图形时的鼠标光标
调用PG_METH_BOARD_Cursor方法可设置图案类型下的鼠标光标,让用户可以直观地知道当前的绘图状态。
3) 实现橡皮功能
白板共享类没有专门的橡皮功能,但可以用绘制线条的方法来实现橡皮。设置线条的颜色与背景颜色相同、设置较宽的线条宽度、设置橡皮形状的鼠标光标,绘制这样的线条时就等同于橡皮的效果。
4) 保存和载入文件
调用 PG_METH_BOARD_Save方法把当前白板的内容保存到指定的图片文件。调用PG_METH_BOARD_Load方法把指定图片文件的内容装入到白板中。这里的图片文件必须是“.png”文件。
1) 顺序传输模式
顺序传输模式是缺省的传输模式。使用该模式时,系统优先按照从前到后的顺序获取数据块。只有当某个数据块还没有源时,才跳到后面获取已经有源的数据块。这种模式的用途是传输媒体流文件,按照从前到后的顺序获取数据块有利于媒体流文件一边下载一边播放。
2) 分散传输模式
分散传输模式用PG_ADD_SHARE_Distribute选项开启。与顺序传输模式相反,分散传输模式尽力避免按照从前到后的顺序传输数据块。这种模式的用途是尽量保持参与共享的节点以相同的进度获取文件,避免某些节点过早传输完成后就关闭了共享。
3) 文件的存储和种子
调用PG_METH_SHARE_Open 方法打开文件分块共享对象时,系统先检查指定的本地存储路径下是否存在该文件。如果文件不存在,则系统创建两个文件分别用来存储文件数据块和传输的状态。这两个文件的文件名分别为共享文件名加上后缀“.pgshs”和“.pgshi”。文件传输完成后系统把“.pgshi”文件删除,把“.pgshs”重命名为共享文件名。例如,假设共享的文件名为“xxxx.avi”,则系统创建的两个文件名分别为“xxxx.avi.pgshs”和“xxxx.avi.pgshi”,传输完成后系统把“xxxx.avi.pgshi”删除,把“xxxx.avi.pgshs”重命名为“xxxx.avi”。
某个节点获取到所有的文件数据块后,作为种子给其他节点继续共享文件。
4) 转发到本地HTTP服务器
控件提供了本地HTTP服务器功能,可以在节点本地的私网地址或环回地址上启动一个HTTP服务器,允许HTTP客户端在本地通过HTTP方式访问Peergine的内容。文件分块共享类能够把正在传输的文件数据实时转发到本地HTTP服务器上,提供给HTTP客户端访问。
使用HttpConfig命令启动本地HTTP服务器,请参考“控件的命令列表”章节。调用PG_METH_SHARE_Open方法打开文件分块共享对象时,如果指定了HttpURL参数,则该文件分块共享对象在本地HTTP服务器上建立一个转发关联。当获取到数据块时,会实时转发到本地HTTP服务器上。HTTP客户端可以使用HttpURL参数指定的URL从HTTP服务器下载共享文件。
这个功能的用途是方便实现媒体流文件的一边下载一边播放。使用顺序传输模式获取媒体流文件并实时转发到本地HTTP服务器上,然后使用具有网络播放功能的播放器播放该媒体流文件的URL。
10. 使用数据表传输类(PG_CLASS_Table)
1) 数据表传输
数据表传输类以类似操作数据库的方式,在多点之间传输数据。一个数据表传输对象对应一个数据表,数据表内的数据以记录、字段的方式存储。在一个节点上调用PG_METH_TABLE_Insert、PG_METH_TABLE_Update和PG_METH_TABLE_Delete方法对数据表记录进行插入、修改和删除时,数据所作的变更会实时地同步到通信组内的其他节点。调用PG_METH_TABLE_Query方法查询或同步到来自其他节点的数据变更时,系统调用PG_METH_TABLE_Report方法上报给应用程序。
2) 文件传输模式
文件传输模式是数据表传输类的增强功能,用PG_ADD_TABLE_File选项开启。开启文件传输模式后,数据表的一条记录存储一个文件的属性信息,包括URL、路径、长度、修改时间、摘要和传输状态。数据表同步文件属性信息的同时,也把文件内容也同步到通信组内的其他节点。请参考“说明:文件传输模式”章节。
3) 强制同步传输
如果数据表中某些记录已经没有源(添加这些记录的节点已经不在通信组里了),则数据表的同步操作就会停止在这些记录上,不能再继续传输数据,这种情况称为记录空洞(Hole)。调用PG_METH_TABLE_Sync方法可以跳过这些没有源的记录继续同步后面有源的记录。
11. 使用媒体流直播类(PG_CLASS_Live)
1) 媒体流的播放和收看
媒体流直播类支持三种媒体流类型:实时捕捉的音频流、实时捕捉的视频流和播放AVI文件影音流。在直播通信组中只能由一个节点作为源节点播放媒体流,其他节点都是收看节点。如果通信组内存在2个以上的源节点,则会导致直播状态混乱。调用PG_METH_LIVE_Open方法打开媒体流直播对象后,还需要调用PG_METH_LIVE_Ctrl方法执行PG_LIVE_CTRL_Play动作,才能开始播放或收看媒体流。在收看节点上,媒体流要经过一段时间的缓冲后才输出。
2) 媒体源的切换
媒体流直播过程中有时需要切换到新的媒体源,恰当的操作能使切换过程平滑,产生的停顿较短。切换媒体源有2种情况:
(1) 在同一个节点上切换不同的媒体流,例如播放另外一个AVI文件。这种情况时,应先调用PG_METH_LIVE_Close方法关闭原来的媒体流,再调用PG_METH_LIVE_Open方法打开新的媒体流,然后执行PG_LIVE_CTRL_Play动作开始播放。
(2) 在不同的节点上切换不同的媒体流,例如切换到另外一个节点的实时捕捉视频流。这样情况时,可先在新的源节点上调用PG_METH_LIVE_Open打开媒体流,但不要执行PG_LIVE_CTRL_Play动作。待老的源节点上调用PG_METH_LIVE_Close方法关闭原来的媒体流后,新的源节点上立即执行PG_LIVE_CTRL_Play动作开始播放。
不管是哪种情况,切换前和切换后的媒体流类型和媒体流格式必须一致,否则收看节点将不接受新的媒体流。
3) 媒体流录制
在收看节点上调用PG_METH_LIVE_Record方法可以把媒体流录制到 Path参数指定的AVI文件中。如果调用时指定Path参数为空,则停止当前正在进行的录制操作。请参考“音频录制”和“视频录制”章节。
pgATX控件的编程参考:
1. 控件的属性配置项:
1) Control
描述:
指定使能pgATX控件的哪些功能。在缺省情况下,可以使用“控件的OML解析器函数”和“控件的辅助函数”。
参数:
Type:用bit位或操作组合多个值可以同时使能多种功能。控件目前支持以下功能:
1:使能对等通信节点功能。使能对等通信节点功能后“控件的节点功能函数”才能生效。
Update:是否启用在线升级。0为禁用,1为启用。缺省为启用。
Sandbox:设置中间件的沙盒目录路径。必须指定绝对路径且不能包含‘=’、‘;’字符。目录路径必须是存在的。
LogName:LOG文件的文件名前缀。
LogLevel0:第0级LOG信息打印开关。0为关闭,1为打开。缺省为打开。
LogLevel1:第1级LOG信息打印开关。0为关闭,1为打开。缺省为打开。
LogLevel2:第2级LOG信息打印开关。0为关闭,1为打开。缺省为关闭。
LogLevel3:第3级LOG信息打印开关。0为关闭,1为打开。缺省为关闭。
LogFileNum:LOG文件的最多保存个数。
LogFileSize:每个LOG文件的最大长度(字节)。
示例(JavaScript):
// 使能控件的Node功能
pgAtx.Control = “Type=1”;
2) Node
描述:
配置节点的性能参数。
参数:
Type:节点类型。0为普通节点,1为登录服务器节点
Cert:证书文件的路径。作为登录服务器时必须指定此参数(请从本软件作者处获取证书)
MaxPeer:节点对象的最大数目,取值范围:1 ~ 32768
MaxGroup:组对象的最大数目,取值范围:1 ~ 32768
MaxObject:对象的最大数目,取值范围:1 ~ 65534
MaxMCast:组播句柄的最大数目,取值范围:1 ~ 65534
MaxHandle:常驻接口事件队列的最大长度,取值范围:1 ~ 65534
MaxNotify:常驻内部事件队列的最大长度,取值范围:1 ~ 65534
SKTBufSize0:消息流的Socket队列长度(报文个数),取值范围:1 ~ 32768
SKTBufSize1:音频流的Socket队列长度(报文个数),取值范围:1 ~ 32768
SKTBufSize2:视频流的Socket队列长度(报文个数),取值范围:1 ~ 32768
SKTBufSize3:文件流的Socket队列长度(报文个数),取值范围:1 ~ 32768
P2PTryTime:指定P2P穿透尝试的时间(秒)。如果超过这个时间后还不能穿透,则使用转发方式通信。本参数的有效值范围:
等于0:使用默认的P2P穿透尝试时间,默认为6秒。
大于0 且 小于等于 3600:使用本参数指定的P2P穿透尝试时间进行尝试。
大于3600:禁用P2P穿透,直接使用转发通信。
SocketMode:节点的Socket模式(同节点类型Type)
ParamMode:节点函数接口的参数模式。0为二进制(在C/C++编程中使用),1为OML格式。
SocketMDU:指定传输层的最大数据单元(Max Data Unit),默认为1024字节,上限为1280字节。最大数据单元决定传输层发送数据包的大小。如果数据包太大了,遇到MTU比较小的网络时,将导致IP报文分片,传输性能降低。
Option:本节点实例的选项,分别为以下的掩码组合:
0x01:启用网络异常时自动重新尝试登录(客户端有效)
0x02:启用集群模式的P2P穿透握手机制(服务器端有效)
0x04:启用踢出重复登录的用户功能(服务器端有效)
0x08:启用节点协助转发功能的握手功能(服务器端有效)
示例(JavaScript):
// 指定该节点为服务器和最大的对象数目。如果不指定某个参数的值,则使用系统的缺省值。
pgAtx.Node = “Type=1;MaxObject=256”;
3) Local
描述:
配置节点的本地参数。
参数:
Name: 本地Peer对象的名称。如果该节点为普通节点,则不要指定本地Peer对象的名称。
Addr: 本地节点的网络地址。作为普通节点时,即使指定了本地地址,系统依然会根据服务器的地址选择合适的本地地址使用。只有无法根据服务器地址选择本地地址时,才会使用指定的本地地址。
FwdSpeed:设置本地节点的转发带宽(Kbps)。设置为0,则禁用本节点做转发。缺省为0。
示例(JavaScript):
// 指定服务器节点的名称为“Server”,地址为“0:0:0:192.168.1.6:3000:0”
pgAtx.Local = “Name=Server;Addr=0:0:0:192.168.1.6:3000:0”;
4) Server
描述:
配置节点的服务器参数。
参数:
Name: 服务器Peer对象的名称。如果该节点为服务器,则不要指定服务器Peer对象的名称。也就是说只有作为客户端的时候才需要指定服务器Peer对象的名称。
Addr: 服务器节点的网络地址
Digest: 是否以摘要的方式发送登录密码。0为明文方式,1为摘要方式。如果启用摘要方式,则需要调用PG_METH_PEER_DigVerify方法对密码进行验证。
示例(JavaScript):
// 指定服务器节点的名称为“Server”,地址为“0:0:0:192.168.1.6:3000:0”,以摘要方式发送密码
pgAtx.Server = “Name=Server;Addr=0:0:0:192.168.1.6:3000:0;Digest=1”;
5) Relay
描述:
配置中继服务的器的隧道参数,可以同时指定多个隧道。节点会自动选择可用的隧道。参考“配置和运行中继服务器”章节
参数:
Type:中继转发的隧道协议类型。0为TCP隧道,1为HTTP隧道,2为WebSocket隧道(未支持)
Load:中继服务器的负荷
Addr:中继服务器的侦听地址
示例(JavaScript):
// 指定2个隧道参数。第1个为HTTP隧道/IPV6地址,第2个为TCP隧道/IPV4地址。
pgAtx.Relay = “(Relay0){(Type){1}(Load){0}(Addr){FE800000:0:01B05996:42CFB70D:80:0}} (Relay1){(Type){0}(Load){0}(Addr){0:0:0:202.101.1.20:443:0}}”;
6) Class
描述:
指定使能的Peergine 功能类以及每种类的最大实例数。本配置项的格式为“类名称:类的最大实例数”,可以同时配置多个类,用分号“;”隔开。注:PG_CLASS_Peer 和PG_CLASS_Group类是系统的内建类,由系统在控件初始化时默认使能。
参数:
PG_CLASS_Data:消息传输类
PG_CLASS_File:文件传输类
PG_CLASS_Audio:音频传输类
PG_CLASS_Video:视频传输类
PG_CLASS_Board:白板共享类
PG_CLASS_Share:文件分块共享类
PG_CLASS_Table:数据表分发类
PG_CLASS_Live:媒体流直播类
示例(JavaScript):
// 类名称的冒号后面的数字指定该类的最大实例数。
pgAtx.Class=“PG_CLASS_Data:8;PG_CLASS_File:16;PG_CLASS_Audio:4;PG_CLASS_Video:4”;
7) OnExtRequest
描述:
指定一个处理请求的回调函数。当控件接收到其他节点的请求时,通过此函数上报给应用程序,处理该请求。
原型:
int OnExtRequest(sObject, uMeth, sIn, uHandle, sPeer)
参数:
sObject: [字符串] 对象名称
uMeth: [整型] 操作方法,参考每种类型的方法定义。
sIn: [字符串] 请求的输入参数,OML格式
uHandle: [整型] 请求句柄,在ObjectExtReply()函数中返回控件。
sPeer: [字符串] 发出请求的对等节点
返回值:
[整型] -1: 异步处理,0: 成功,>0: 失败的错误码。如果返回值为-1,表示处理还没有完成,后续需要调用ObjectExtReply()函数发送应答。如果返回值大于等于0,则表示处理已经完成,返回值就是应答的错误码。
示例(JavaScript):
function pgOnExtRequest(sObject, uMeth, sIn, uHandle, sPeer)
{
// TO DO …
pgAtx.ObjectExtReply(sObject, 0, “”, uHandle);
return -1;
}
pgAtx.OnExtRequest = pgOnExtRequest;
8) OnReply
描述:
指定一个处理应答的回调函数。当接收到异步操作应答时,系统调用该函数。
原型:
int OnReply(sObject, uErr, sOut, sParam)
参数:
sObject:[字符串] 对象名称
uErr:[整型] 错误码
sOut:[字符串] 应答的输出参数,OML格式
sParam:[字符串] 用户参数,就是在ObjectRequest()函数调用时输入的sParam参数。
返回值:
[整型] 0: 成功,>0: 失败的错误码。
示例(JavaScript):
function pgOnReply(sName, uErr, sOut, sParam)
{
// TO DO …
return 0;
}
pgAtx.OnReply = pgOnReply;
2. 控件的节点功能函数:
1) int ObjectAdd(sObject, sClass, sGroup, uFlag)
描述:
增加一个对象。
参数:
sObject:[字符串] 对象的名称。注意:如果一个同名对象已经存在,则直接返回成功。
sClass:[字符串] 该对象的类型,参考“节点功能类的编程参考”章节。
sGroup:[字符串] 该对象关联的组。它是一个PG_CLASS_Peer或PG_CLASS_Group类型的对象的名称。为空表示不指定关联的组。
uFlag:[整型] 指定创建对象的选项标志,参考“节点功能类的编程参考”中的“标志”章节。
返回值:
[整型] 1: 成功,0: 失败。
示例(JavaScript):
// 添加一个名为“OnlineGroup”的通信组对象。该对象的关联组为节点“Server”。
pgAtx.ObjectAdd(“OnlineGroup”, “PG_CLASS_Group”, “Server”, 0x1);
2) void ObjectDelete(sObject)
描述:
删除一个对象。
参数:
sObject:[字符串] 对象的名称
返回值:
无
示例(JavaScript):
// 删除名为“OnlineGroup”的对象
pgAtx.ObjectDelete(“OnlineGroup”);
3) String ObjectGetClass(sObject)
描述:
获取对象的类型。
参数:
sObject:[字符串] 对象的名称
返回值:
[字符串] 该对象的类型。
示例(JavaScript):
// 获取名为“OnlineGroup”的对象的类型
var sClass = pgAtx.ObjectGetClass(“OnlineGroup”);
4) int ObjectSetGroup(sObject, sGroup)
描述:
指定对象的关联组。
参数:
sObject:[字符串] 对象的名称
sGroup:[字符串] 该对象关联的组。它是一个PG_CLASS_Peer或PG_CLASS_Group类型的对象的名称。当此参数为空时,删除之前关联的组。
返回值:
[整型] 1: 成功,0: 失败。
示例(JavaScript):
// 删除对象“OnlineGroup”的关联组
pgAtx.ObjectSetGroup(“OnlineGroup”, “”);
5) String ObjectGetGroup(sObject)
描述:
获取对象的关联组。
参数:
sObject:[字符串] 对象的名称
返回值:
[字符串] 该对象的组。
示例(JavaScript):
// 获取对象“OnlineGroup”的关联组
var sGroup = pgAtx.ObjectGetGroup(“OnlineGroup”);
6) int ObjectSync(sObject, sPeer, uAction)
描述:
主动触发通信对象同步,也就是主动触发通信对象建立会话连接。
参数:
sObject:[字符串] 对象的名称
sPeer:[字符串] 对等节点名称。如果此参数为空,则与通信范围内的所有节点都进行同步。
uAction:[整型] 同步动作,1: 已同步,0: 去同步。
返回值:
[整型] 1: 成功,0: 失败。
示例(JavaScript):
// 触发“OnlineGroup”对象在“Server”节点上进行同步。
pgAtx.ObjectSync(“OnlineGroup”, “Server”, 1);
7) int ObjectRequest(sObject, uMeth, sIn, sParam)
描述:
发送一个请求操作。
参数:
sObject:[字符串] 对象的名称
uMeth:[整型] 请求的方法ID,参考类型的方法定义。
sIn:[字符串] 请求的输入参数。
sParam:[字符串] 用户定义参数,在OnReply()回调函数中原样返回。
返回值:
[整型] -1: 异步处理,0: 成功,>0: 错误码。如果返回-1,说明操作正在异步处理,等待处理完成后通过OnReply()回调函数上报结果。如果返回>=0,则操作已经完成,返回值表示执行结果。
示例(JavaScript):
// 给“Server”节点发送一个RPC请求。
// PG_CLASS_Peer类的PG_METH_PEER_Call方法的ID为35
pgAtx.ObjectRequest(“Server”, 35, “How are you?”, “SendCall”);
8) int ObjectExtReply(sObject, uErr, sOut, uHandle)
描述:
应答一个异步请求。
参数:
sObject:[字符串] 对象的名称
uErr:[整型] 错误码。
sOut:[字符串] 应答的输出参数
uHandle:[整型] 请求句柄,由OnExtRequest()函数输入的uHandle参数。
返回值:
[整型] 0: 成功,>0: 失败的错误码。
示例(JavaScript):
// 应答一个请求。
pgAtx.ObjectExtReply(“Server”, 0, “I am fine.”, uHandle);
9) String ObjectEnum(sObject, sClass)
描述:
枚举遍历指定类型的所有对象。
参数:
sObject:[字符串] 上一个对象的名称,起始的对象名称为空字符串。
sClass:[字符串] 对象的类型。
返回值:
[字符串] 下一个对象的名称,返回空字符串表示枚举结束。
示例(JavaScript):
var sObj = “”; // 起始的对象名称为空
while (true) {
var sObjNext = pgAtx.ObjectEnum(sObj, “PG_CLASS_Video”);
if (sObjNext == “”) {
// 返回对象名为空时,结束枚举。
break;
}
alert(“Object: ” + sObjNext);
sObj = sObjNext;
}
10) int PostMessage(sMsg)
描述:
发送消息给控件的消息队列。控件处理消息后,会通过OnExtRequest()回调函数上报消息。上报的消息内容与发送的消息内容一致。
参数:
sMsg:[字符串] 任意字符串。
返回值:
[整型] 0: 成功,>0: 失败的错误码。
示例(JavaScript):
// 发送消息给控件。
pgAtx.PostMessage(“012345679acbdef”);
11) int PumpMessage(uLoop)
描述:
处理控件的消息循环。控件与应用程序之间的交互需要通过消息队列投递消息。在没有界面线程的JavaScript容器(或者Java应用程序)中运行控件时,由于没有消息循环,不能与应用程序交互。这种情况下,可以在JavaScript容器的运行线程中主动调用PumpMessage()函数来处理消息。
参数:
uLoop:[整型] 0:每处理完一个消息后,该函数返回;1:该函数循环处理消息,直到进程退出前才返回。
返回值:
[整型] 1: 成功,0: 失败(收到WM_QUIT消息)。
示例(JavaScript):
// 循环处理消息。
while (pgAtx.PumpMessage(0)) {
// TO DO
}
12) int Start(uOption)
描述:
启动节点功能
参数:
uOption:[整型] 选项,必须为0。
返回值:
[整型] 0: 成功,>0: 失败的错误码。
示例(JavaScript):
// 启动一个 Node的功能
pgAtx.Start(0);
13) void Stop()
描述:
停止节点功能。(C++、JNI、Object-C接口封装的中间件支持此函数,ActiveX不支持此函数。)
重要:不能在OnExtRequest()和OnReply()回调函数中调用此Stop()函数。
参数:
无
返回值:
无
示例(Java):
// 停止一个 Node的功能
Node.Stop();
3. 控件的OML解析器函数:
1) String omlEncode(sEle)
描述:
对指定字符串进行OML编码。如果该字符串中包含OML的标记字符,则这些标记字符将转换成转义后的标记,请参考“对象标记语言(OML)”章节。
参数:
sEle:[字符串] 需要编码的字符串
返回值:
[字符串] 编码后的字符串。
示例(JavaScript):
var sEncEle = pgAtx.omlEncode(“abc(efg[hij{klm”);
2) String omlDecode(sEle)
描述:
对指定字符串进行OML解码。
参数:
sEle:[字符串] 需要解码的字符串
返回值:
[字符串] 解码后的字符串。
示例(JavaScript):
var sDecEle = pgAtx.omlDecode(“abc&Aefg&Chij&Eklm”);
3) String omlSetName(sEle, sPath, sName)
描述:
设置一个OML元素的名称。
参数:
sEle:OML字符串
sPath:需要设置名称的OML元素在整个OML字符串中的路径
sName:设置的新名字。不需要对此参数进行OML编码。
返回值:
[字符串] 设置元素名称后的整个OML字符串。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sNewEle = pgAtx.omlSetName(sEle, “Name0”, “NameX”);
4) String omlSetClass(sEle, sPath, sClass)
描述:
设置一个OML元素的类型
参数:
sEle:OML字符串
sPath:需要设置名称的OML元素在整个OML字符串中的路径
sClass:设置的新类型。不需要对此参数进行OML编码。
返回值:
[字符串] 设置元素类型后的整个OML字符串。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sNewEle = pgAtx.omlSetClass(sEle, “Name0”, “ClassX”);
5) String omlSetContent(sEle, sPath, sContent)
描述:
设置一个OML元素的内容
参数:
sEle:OML字符串
sPath:需要设置名称的OML元素在整个OML字符串中的路径
sContent:设置的新内容。不需要对此参数进行OML编码。
返回值:
[字符串] 设置元素内容后的整个OML字符串。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sNewEle = pgAtx.omlSetContent(sEle, “Name0”, “XXXXX”);
6) String omlNewEle(sName, sClass, sContent)
描述:
生成一个OML元素字符串
参数:
sName:元素的名称。不需要对此参数进行OML编码。
sClass:元素的类型。不需要对此参数进行OML编码。
sContent:元素的内容。不需要对此参数进行OML编码。
返回值:
[字符串] 生成的OML元素字符串。
示例(JavaScript):
var sNewEle = pgAtx.omlNewEle(“Name0”, “Class0”, “aaaaaaaaaa”);
7) String omlGetEle(sEle, sPath, uSize, uPos)
描述:
从一个OML字符串中获取指定的OML元素
参数:
sEle:OML字符串
sPath:要获取的元素在整个OML字符串的路径
uSize:获取OML元素的个数
uPos:获取OML元素的起始位置
返回值:
[字符串] 获取到的OML元素。
示例(JavaScript):
var sEle = “(PeerList){(Peer0){}(Peer1){}(Peer2){}(Peer4){}}”;
var sSubEle = pgAtx.omlGetEle(sEle, “PeerList.”, 2, 0);
8) String omlDeleteEle(sEle, sPath, uSize, uPos)
描述:
从一个OML字符串中删除指定的OML元素
参数:
sEle:OML字符串
sPath:要删除的元素在整个OML字符串的路径
uSize:删除OML元素的个数
uPos:删除OML元素的起始位置
返回值:
[字符串] 删除指定元素后的OML字符串。
示例(JavaScript):
var sEle = “(PeerList){(Peer0){}(Peer1){}(Peer2){}(Peer4){}}”;
var sSubEle = pgAtx.omlDeleteEle(sEle, “PeerList.”, 3, 1);
9) String omlGetName(sEle, sPath)
描述:
获取指定OML元素的名称
参数:
sEle:OML字符串
sPath:要获取名称的元素在整个OML字符串的路径
返回值:
[字符串] 获取到的元素名称。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sName = pgAtx.omlGetName(sEle, “”);
10) String omlGetClass(sEle, sPath)
描述:
获取指定OML元素的类型
参数:
sEle:OML字符串
sPath:要获取类型的元素在整个OML字符串的路径
返回值:
[字符串] 获取到的元素类型。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sClass = pgAtx.omlGetClass(sEle, “Name1”);
11) String omlGetContent(sEle, sPath)
描述:
获取指定OML元素的内容
参数:
sEle:OML字符串
sPath:要获取内容的元素在整个OML字符串的路径
返回值:
[字符串] 获取到的元素内容。
示例(JavaScript):
var sEle = “(Name0)[Class0]{aaaaa}(Name1)[Class0]{bbbb}”;
var sContent = pgAtx.omlGetContent(sEle, “Name1”);
4. 控件的辅助函数:
1) String utilGetWndRect()
描述:
获取控件窗口的尺寸和句柄。
参数:
无
返回值:
[字符串] 控件窗口的尺寸和句柄信息,OML格式。
格式样例:(PosX){0}(PosY){0}(SizeX){60}(SizeY){80}(Handle){9847387}
示例(JavaScript):
// 打开一个本地视频预览,并在控件窗口上显示预览图像。
pgAtx.ObjectAdd(“VideoPreview”, “PG_CLASS_Video”, “”, 0x2);
var sWndEle = pgAtx.utilGetWndRect();
var sInEle = “(Code){0}(Mode){0}(Rate){200}(Wnd){” + sWndEle + “}”;
pgAtx.ObjectRequest(“VideoPreview”, 32, sInEle, “OpenPreview”);
2) String utilCmd(sCmd, sParam)
描述:
执行控件命令的函数。
参数:
sCmd:命令名,参考“控件的命令列表”章节。
sParam:命令参数
返回值:
[字符串] 返回命令执行的结果。
示例(JavaScript):
// 弹出文件选择对话框
var sRes = pgAtx.utilCmd(“DlgFile”, “(Open){1}(Ext){}(File){}(Flag){0}(Filter){}”);
5. 控件的命令列表:
1) PathGet
描述:
获取控件沙盒目录下的一个子目录的全路径,如果该子目录不存在,则创建该子目录。
参数:
Type:子目录的名称
返回值:
[字符串] 所获取的路径。
2) FileList
描述:
获取指定文件目录下的文件列表
参数:
Dir:指定需要获取文件列表的目录(受沙盒控制)
返回值:
[字符串] OML格式,包含以下参数。例如:(File1.txt){(Size){1000}(Time){2011-10-21,15:03:55}}
File:文件名
Size:文件的大小(字节)
Time:修改时间,格式:YYYY-MM-DD,HH:MM:SS
3) FileCopy
描述:
复制一个文件。控件的文件操作只限制在沙盒目录范围内。该沙盒目录缺省为当前用户的Documents目录下的Peergine子目录。所以,需要对沙盒目录之外的文件进行操作时,使用此命令来复制文件。
参数:
Src:源文件路径(受沙盒控制)。当此参数为空时,系统弹出文件对话框让用户选择源文件路径。
Dst:目标文件路径(受沙盒控制)。当此参数为空时,系统弹出文件对话框让用户选择目标文件路径。
Filter:指定文件对话框中的文件扩展名过滤条件,样例:”Png Files(*.png)|*.png||All files(*.*)|*.*”。
返回值:
[整型] 1:成功,0:失败
4) FileMove
描述:
移动或重命名一个文件.
参数:
Src:源文件路径(受沙盒控制)。
Dst:目标文件路径(受沙盒控制)。
返回值:
[整型] 1:成功,0:失败
5) FileInfo
描述:
获取指定文件的信息,包括文件的大小、修改时间和摘要。
参数:
Path:指定的文件路径。
返回值:
[字符串] OML格式,包含以下参数。例如:(Size){1000}(Time){2011-10-21,15:04:23}(Hash){}
Size:文件的大小(字节)
Time:文件的修改时间,格式:YYYY-MM-DD,HH:MM:SS
Hash:文件的摘要,用SHA256算法生成,Base64格式。
6) FileClean
描述:
清除指定沙盒子目录下的所有文件。
参数:
Type:子目录的名称
返回值:
无
7) DlgFile
描述:
弹出文件对话框,让用户选择需要打开或保存的文件。
参数:
Open:1为打开文件,0为保存文件
Ext:在对话框里显示的缺省扩展名
File:在对话框里显示的缺省文件名
Filter:文件扩展名过滤条件,样例:”Png Files(*.png)|*.png||All files(*.*)|*.*”。
返回值:
[字符串] OML格式,包含以下参数。例如:(Path){c:\temp\xxxx.txt}(File){xxxx.txt}
Path:文件的全路径
File:文件名
8) DlgDir
描述:
弹出文件目录对话框,让用户选择目录。
参数:
Dir:在对话框中初始化的目录。
返回值:
[字符串] OML格式,包含以下参数。例如:(Dir){c:\temp\image}
Dir:用户选择的目录。
9) CacheAdd
描述:
往文件缓冲内添加一个文件,同时把该文件复制到文件缓冲目录下。
参数:
Name: 文件缓冲区的名称。
URL:指定该文件在缓冲中的唯一标识。
Copy:指定需要复制的文件路径(受沙盒控制)。如果不需要复制文件,则此参数为空。
Time:设置文件的修改时间。
返回值:
[字符串] OML格式,包含以下参数。
例如:(Local){c:\My Document\Peergine\Cache\xxxx[0].txt}(Exist){1}
Local:文件在缓冲目录下的路径。
Exist:该记录是否已经在缓冲区存在。
10) CacheDelete
描述:
从文件缓冲区中删除指定的文件
参数:
Name: 文件缓冲区的名称。
URL:文件在缓冲区中的唯一标识。
返回值:
无
11) CacheSetDir
描述:
指定控件的文件缓冲目录。
参数:
Name: 文件缓冲区的名称。
Dir:文件缓冲目录的路径(受沙盒控制)。如果路径为非空字符串,则启用该文件缓冲区。如果路径为空字符串,则关闭该文件缓冲区。
返回值:
[整型] 1:成功,0:失败
12) CacheGetInfo
描述:
获取文件缓冲区中指定文件的信息。
参数:
Name: 文件缓冲区的名称。
URL:文件在缓冲区中的唯一标识。
返回值:
[字符串] OML格式,包含以下参数。例如:(URL){File:xxxx.txt}(Path){c:\My Document\Peergine\ Cache\xxxx[0].txt}(Size){1000}(Time){2011-10-21,16:21:02}(Hash){}
URL:文件在缓冲区中的唯一标识。
Path:文件在缓冲目录中的全路径。
Size:文件的大小(字节)
Time:文件修改的时间,格式:YYYY-MM-DD,HH:MM:SS
Hash:文件的摘要,SHA256算法生成,Base64格式。
13) CookieSet
描述:
在本地存储一个cookie。
参数:
Name:Cookie的名字
Value:Cookie的值
Expire:Cookie的过期时间,格式:YYYY-MM-DD,HH:MM:SS
返回值:
[整型] 1:成功,0:失败
14) CookieGet
描述:
读取一个本地Cookie的值。
参数:
Name:Cookie的名字
返回值:
[字符串] OML格式,包含以下参数。例如:(Value){xxxxxx}
Value:Cookie的值
15) CookieDelete
描述:
删除一个本地Cookie。
参数:
Name:Cookie的名字。
返回值:
无
16) ImageConvert
描述:
转换图片格式和缩放图片尺寸。通过文件名的后缀来指定图片的格式,如果输入、输出的文件名后缀不相同,则转换文件格式。支持的图片格式为*.bmp、*.png和*jpg三种。通过Width和Height参数的指定尺寸缩放的大小和方式,如下表:
宽Width | 高Height | 缩放方式 |
不等于0 | 不等于0 | 缩放后,宽和高不超过Width和Height,宽和高的比率保持不变 |
不等于0 | 等于0 | 缩放后,宽为Width,宽和高的比率保持不变 |
等于0 | 不等于0 | 缩放后,高为Height,宽和高的比率保持不变 |
等于0 | 等于0 | 不缩放尺寸 |
参数:
In:输入的图片文件路径(受沙盒控制)
Out:输出的图片文件路径(受沙盒控制)
Width:输出的图片宽度(像素)
Height:输出的图片高度(像素)
返回值:
[整型] 1:成功,0:失败
17) HttpAdd
描述:
在本地HTTP服务器中添加一个文件。
参数:
URL:该文件从HTTP访问的URI
Local:该文件的本地存储路径。
返回值:
[整型] 1:成功,0:失败
18) HttpDelete
描述:
从本地HTTP服务器中删除一个文件。
参数:
URL:该文件从HTTP访问的URI
返回值:
[整型] 1:成功,0:失败
19) HttpConfig
描述:
设置本地HTTP服务器的侦听地址且启动HTTP服务器。
参数:
Addr:HTTP服务器的侦听地址,格式为:X:X:X:X:Port:Info。此地址只能是IPV4 的私网IP地址或本地环回地址。例如:0:0:0:7f000001:80:0或0:0:0:127.0.0.1:80:0。如果指定的侦听地址为0:0:0:0:0:0,则关闭HTTP服务器。
返回值:
[整型] 1:成功,0:失败
20) AviPlay
描述:
播放一个AVI文件。控件目前支持的AVI视频/音频格式为:
音频:PCM或G.711A编码、16bit采样、采样速率11 KHz、单通道。
视频:MJPEG(A)和VP8视频压缩格式。
如果你的AVI文件格式不符合,请先用工具转换成以上的格式后再播放。
参数:
File:AVI文件的路径
Wnd:显示AVI视频图像的窗尺寸口和句柄。格式样例:(PosX){0}(PosY){0}(SizeX){60}(SizeY){80} (Handle){9847387}。此参数可以用utilGetWndRect()函数从控件获取。
返回值:
[整型] 1:成功,0:失败
21) AviStop
描述:
停止播放一个AVI文件。
参数:
File:AVI文件的路径
返回值:
[整型] 1:成功,0:失败
22) AviGetInfo
描述:
获取一个AVI文件的信息(未实现)。
参数:
无
返回值:
无
23) TrayIcon
描述:
安装托盘图标(未实现)。
参数:
Icon:图标文件路径,文件名的后缀必须为.ico。此参数为空时,卸装托盘图标。
Menu:鼠标右键点击托盘图标时弹出的菜单。此参数为菜单项的信息,格式为:(菜单ID){菜单文本}。样例:(0){显示窗口}(1){设置}(){}(2){退出}。OML名称为空的菜单项为分隔线。
返回值:
[整型] 1:成功,0:失败
事件:
鼠标左键点击托盘图标:通过OnExtRequest()函数上报点击事件。格式为:(TrayIcon){}
选择托盘图标的右键菜单:通过OnExtRequest()函数上报选择的菜单ID。格式为:(TrayIcon){菜单ID}
24) TracePopup
描述:
在屏幕的右下角弹出一个提示框(未实现)。
参数:
Title:提示框标题
Text:提示框中显示的内容。
返回值:
[整型] 1:成功,0:失败
事件:
鼠标键击提示框内容:通过OnExtRequest()函数上报点击事件。格式为:(TracePopup){自定义事件内容}。
25) CapScreen
描述:
从屏幕截取一个图片。
参数:
Full:是否要全屏截图。0为只截取鼠标选中的区域,1为全屏截取(未支持)
Path:存储所截取图片的文件路径,文件名的后缀必须为.png。
返回值:
[整型] 1:成功,0:失败
事件:
截图完成后:通过OnExtRequest()函数上报图片的文件路径。格式为:(Path){文件路径}。
26) Setting
描述:
弹出控件的设置对话框。还可以在控件窗口内点击右键菜单打开设置对话框。
参数:
无
返回值:
[整型] 1:成功,0:失败
27) Version
描述:
获取控件的版本信息。
参数:
无
返回值:
[字符串] OML格式,包含以下参数。例如:(Version){v1.1.2}(OS){Windows}
Version:版本号。
OS:操作系统类型。
6. 其他
1) 错误码
PG_ERR_Normal
值:0
说明:成功
PG_ERR_System
值:1
说明:系统错误
PG_ERR_BadParam
值:2
说明:参数错误
PG_ERR_BadClass
值:3
说明:错误的通信对象类
PG_ERR_BadMethod
值:4
说明:错误的通信对象类方法
PG_ERR_BadObject
值:5
说明:错误的通信对象
PG_ERR_BadStatus
值:6
说明:错误的状态
PG_ERR_BadFile
值:7
说明:错误的文件
PG_ERR_BadUser
值:8
说明:错误的用户
PG_ERR_BadPass
值:9
说明:错误的密码
PG_ERR_NoLogin
值:10
说明:还没有登录
PG_ERR_Network
值:11
说明:网络错误
PG_ERR_Timeout
值:12
说明:操作超时
PG_ERR_Reject
值:13
说明:拒绝访问
PG_ERR_Busy
值:14
说明:系统正忙
PG_ERR_Opened
值:15
说明:已经打开
PG_ERR_Closed
值:16
说明:已经关闭
PG_ERR_Exist
值:17
说明:对象或资源已经存在
PG_ERR_NoExist
值:18
说明:对象或资源不存在
PG_ERR_NoSpace
值:19
说明:没有空间了
PG_ERR_BadType
值:20
说明:错误的类型
PG_ERR_CheckErr
值:21
说明:检查Peer对象信息和状态错误
PG_ERR_BadServer
值:22
说明:错误的服务器
PG_ERR_BadDomain
值:23
说明:错误的域
PG_ERR_NoData
值:24
说明:没有数据
PG_ERR_Unknown
值:255
说明:未知错误
节点功能类的编程参考:
1. 类的通用选项和方法
1) 描述:
本章节列出各种通信对象类都共用的选项和方法。
2) 选项:
PG_ADD_COMMON_Sync
掩码:0x10000
说明:使能该通信对象的PG_METH_COMMON_Sync方法
PG_ADD_COMMON_Error
掩码:0x20000
说明:使能该通信对象的PG_METH_COMMON_Error方法
PG_ADD_COMMON_Encrypt
掩码:0x40000
说明:对该通信对象的通信数据进行加密传输。
PG_ADD_COMMON_Compress
掩码:0x80000
说明:对该通信对象的通信数据进行压缩传输。
3) 方法:
PG_METH_COMMON_Sync
ID:0
说明:上报通信对象的同步状态。当通信对象同步或去同步时,系统会调用此方法。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Action){1}
Action:同步的动作。0为去同步,1为已同步。
发送应答参数:无此操作
接收请求参数:无此操作
PG_METH_COMMON_Error
ID:1
说明:上报错误信息
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Meth){32}(Error){1}
Meth:产生错误的方法
Error:错误码
发送应答参数:无此操作
接收请求参数:无此操作
PG_METH_COMMON_SetOption
ID:2
说明:设置通信对象的扩展选项参数。各个通信对象类根据实际需要实现此方法。。
交互方式:方式7
发送请求参数:样例:(Item){1}(Value){}
Item:配置参数ID,具体值由各个通信对象类定义。
Value:配置参数的值
接收请求参数:无此操作
发送应答参数:无此操作
接收请求参数:无此操作
PG_METH_COMMON_GetOption
ID:3
说明:获取通信对象的扩展选项参数。各个通信对象类根据实际需要实现此方法。
交互方式:方式5
发送请求参数:样例:(Item){1}
Item:配置参数ID,具体值由各个通信对象类定义。
接收请求参数:无此操作
发送应答参数:无此操作
接收请求参数:样例:(Item){1}(Value){}
Item:配置参数ID,具体值由各个通信对象类定义。
Value:配置参数的值
2. PG_CLASS_Peer类:
1) 描述:
节点类。
2) 选项:
PG_ADD_PEER_Self
掩码:0x1
说明:指定该Peer对象为本地节点的自身对象
PG_ADD_PEER_Server
掩码:0x2
说明:指定该 Peer对象为登录服务器节点对象
PG_ADD_PEER_Static
掩码:0x4
说明:指定该 Peer对象为静态节点对象。静态节点对象要调用PG_METH_PEER_SetAddr方法设置地址后才能使用。
PG_ADD_PEER_Digest
掩码:0x8
说明:登录的时候使用摘要方式发送密码。只能与PG_ADD_PEER_Serve选项组合使用。
PG_ADD_PEER_Disable
掩码:0x10
说明:禁用该Peer节点的所有访问权限。后续可以使用PG_METH_PEER_AccessCtrl方法修改该Peer的访问权限。
3) 方法:
PG_METH_PEER_Login
ID:32
说明:登录到服务器。登录成功后,系统会自动创建本地节点的自身对象,对象名就是用户名。
交互方式:方式1
发送请求参数:样例:(User){NodeA}(Pass){****}(Param){}
User:用户名,就是客户端节点自身对象的名称
Pass:密码
Param:参数,由应用程序定义
接收请求参数:样例:(Addr){0:0:0:192.168.1.6}(User){NodeA}(Pass){****}(Param){}
Addr:登录节点的地址
User:登录用户名,就是客户端节点自身对象的名称
Pass:密码
Param:参数,由应用程序定义
发送应答参数:样例:(Expire){30}(Type){0}(Sess){}(Param){}
Expire:登录老化时间(秒)
Type:用户的类型,缺省为0(将来使用)
Option:选项,bit位掩码的组合。指定为0x01时,在登录应答完成后,内部删除该节点对象。
Sess:登录会话信息,由应用程序定义
Param:参数,由应用程序定义
接收应答参数:样例:(Type){0}(Sess){}(Parm){}
Type:用户的类型,缺省为0(将来使用)
Sess:登录会话信息,由应用程序定义
Param:参数,由应用程序定义
PG_METH_PEER_Logout
ID:33
说明:注销登录。注销后,系统会自动删除本地节点的Peer对象。
交互方式:方式4
发送请求参数:空
接收请求参数:样例:(User){NodeA}
User:注销登录的节点名称
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_Status
ID:34
说明:根据节点对象的名称解析该节点的地址、代理地址和登录状态。此方法只有在组网中有多个登录服务器节点组成集群功能时使用。如果请求解析的节点和被解析的节点都登录到同一个登录服务器节点上,则此方法不会被调用。系统在控件内部处理完解析请求并返回应答,不会上报到应用程序。当请求解析的节点和被解析的节点登录在不同的登录服务器节点上时,系统调用此方法把请求上报给应用程序。由应用程序通过集群组网从被解析的节点所登录的登录服务器节点获取解析结果,并返回给请求解析的节点。
交互方式:方式3
发送请求参数:无此操作(控件内部自行发送请求)
接收请求参数:样例:(User){NodeA}
User:指定节点对象的名称。
发送应答参数:样例: (Type){0}(Addr){0:0:0:192.168.1.6:1234:0} (Proxy){0:0:0:192.168.1.12:1112:0}
Type:用户的类型,缺省为0(将来使用)
Addr:指定节点的地址
Proxy:指定节点的Proxy地址
接收应答参数:无此操作(控件内部自行处理应答)
PG_METH_PEER_Call
ID:35
说明:对指定节点对象执行一个RPC操作
交互方式:方式1
发送请求参数:任意字符串,内容和格式由用户定义
接收请求参数:同发送请求参数
发送应答参数:任意字符串,内容和格式由用户定义
接收应答参数:同发送应答参数
PG_METH_PEER_Message
ID:36
说明:给指定节点对象发送一个消息
交互方式:方式4
发送请求参数:任意字符串,内容和格式由用户定义
接收请求参数:同发送请求参数
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_SetAddr
ID:37
说明:设置节点对象的自身地址和代理地址
交互方式:方式7
发送请求参数:样例:(Addr){0:0:0:192.168.1.6:1234:0}(Proxy){0:0:0:192.168.1.1:4567:0}
Addr:指定节点的地址
Proxy:指定节点的代理地址
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_GetInfo
ID:38
说明:获取节点对象的自身地址、代理地址和隧道地址。
交互方式:方式5
发送请求参数:空
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Type){0}(Through){4}(Proxy){202.112.1.100:7781}(AddrLcl){67.89.2.10:56734}(AddrRmt){218.10.4.50:12345}(TunnelLcl){67.89.2.10:56734}(TunnelRmt){218.10.4.50:12345}(PrivateRmt){192.168.1.23:56721}
Type:节点类型,由服务器定义
Through:P2P连接通道的类型,参考“P2P连接通道类型”章节。
Proxy:服务器节点的地址
AddrLcl:本端节点的登录地址
AddrRmt:对端节点的登录地址
TunnelLcl:本端节点的通道地址
TunnelRmt:对端节点的通道地址
PrivateRmt:本端节点的本地地址
PG_METH_PEER_DigGen
ID:39
说明:产生数据的签名。
交互方式:方式5
发送请求参数:样例:(Data){01234567890}(Value){}
Data:需要产生签名的数据(任意字符串)。
Value:(空)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Data){}(Value){YHEm82O44Vhtn05wxue2V4w0TOTXBSZVu9u9Imip1S4=}
Data:(空)。
Value:产生的签名值(Base64格式)。
PG_METH_PEER_DigVerify
ID:40
说明:校验数据的签名。
交互方式:方式7
发送请求参数:样例:(Data){01234567890}(Value){YHEm82O44Vhtn05wxue2V4w0TOTXBSZVu9u9Imip1S4=}
Data:需要校验签名的数据。
Value:需要校验的签名值(Base64格式)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_CheckInfo
ID:41
说明:检查节点的状态信息。
交互方式:方式7
发送请求参数:样例:(Check){}(Value){}(Opion){}
Check:检查类型。
Value:对比的值。
Opion:选项。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_LanScan
ID:42
说明:搜索同一个局域网内的P2P节点。
交互方式:方式5
发送请求参数:样例:(Timeout){3}
Timeout:搜索等待的时间(秒)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Size){2}(PeerList){(Peer0){192.168.1.2:7654}(Peer1){192.168.1.3:7654}}
Size:搜索到的节点个数。
PeerList:节点的地址信息列表
PG_METH_PEER_AgentLogin
ID:43
说明:代理节点登录到服务器。登录成功后,系统会自动创建代理节点对象,对象名就是用户名。
交互方式:方式1
发送请求参数:样例:(User){AgentUser1}(Pass){****}(Param){}
User:用户名,就是客户端节点自身对象的名称
Pass:密码
Param:参数,由应用程序定义
接收请求参数:样例:(User){AgentUser1}(Pass){****}(Param){}
User:登录用户名,就是客户端节点自身对象的名称
Pass:密码
Param:参数,由应用程序定义
发送应答参数:样例:(Param){}
Param:参数,由应用程序定义
接收应答参数:样例:(Param){}
Param:参数,由应用程序定义
PG_METH_PEER_AgentLogout
ID:44
说明:代理节点注销登录。注销后,系统会自动删除代理节点对象。
交互方式:方式4
发送请求参数:样例:(User){AgentUser1}
User:注销登录的节点名称
接收请求参数:样例:(User){AgentUser1}
User:注销登录的节点名称
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_AgentMessage
ID:45
说明:给代理Peer节点发送一个消息。
交互方式:方式4
发送请求参数:样例:(Peer){AgentUser1}(Data){123456abcdef}
Peer:对端的Peer节点名称
Data:消息的数据(字符串)
接收请求参数:样例:(Peer){AgentUser1}(Data){123456abcdef}
Peer:对端的Peer节点名称
Data:消息的数据(字符串)
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_ReloginReply
ID:46
说明:本Peer节点自动重新登录服务器返回时,上报返回的登录结果信息。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(ErrCode){0}(Expire){30}(Type){0}(Sess){}(Param){}
ErrCode:错误码
Expire:登录老化时间(秒)
Type:用户的类型,缺省为0(将来使用)
Sess:登录会话信息,由应用程序定义
Param:参数,由应用程序定义
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_KickOut
ID:47
说明:本Peer节点已经被服务器踢下线(原因是本Peer节点的节点名与其他节点的冲突了)。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Param){0}
Param:保留,必须为0
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_AccessCtrl
ID:48
说明:设置指定Peer节点对各个业务类的访问权限。
交互方式:方式7
发送请求参数:样例:(Class){PG_CLASS_Video}(Ctrl){0}
Class:需要控制权限的业务类名称。
Ctrl:控制权限。0:禁止发送和接收,1:只允许发送,2:只允许接收,3:允许发送和接收。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_PEER_PushOption
ID:49
说明:下发配置选项给指定的Peer节点(只能在服务器节点上调用)。
交互方式:方式9
发送请求参数:样例:(Item){0}(Value){}
Item:选项ID,参考“PG_METH_PEER_PushOption方法的选项”章节。
Value:选项的值
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
4) 扩展选项:
PG_OPTION_PEER_SocketMDU:
Item: 0
说明:给每个节点单独指定最大数据单元(Max Data Unit)。
格式:(Item){0}(Value){1024}
范围:本节点发送给所指定节点的数据在分片时单独使用所指定的最大数据单元。
PG_OPTION_PEER_SocketLAN
Item: 1
说明:使能节点的局域网搜索功能,使其他节点能够搜索到本节点。
格式:“ (Item){1}(Value){ ” + omlEncode(“(Enable){0}(Peer){}(Label){}” + “}”。Enable:1使能,0禁止;Peer:指定搜索的节点名;Label:匹配标签。
范围:可在任何一个节点对象上操作,影响全局。
PG_OPTION_PEER_LoginTimeout
Item: 2
说明:设置登录的超时时间。
格式:(Item){2}(Value){10},Value的单位为秒。
范围:可在任何一个节点对象上操作,影响全局。
PG_OPTION_PEER_CallTimeout
Item: 3
说明:设置Call请求的超时时间。
格式:(Item){3}(Value){10},Value的单位为秒。
范围:可在任何一个节点对象上操作,影响全局。
PG_OPTION_PEER_SocketSelect
Item: 4
说明:设置本节点与指定节点之间通信的方式。
格式:(Item){4}(Value){0}。Value为0:自动选择,Value为1:只用P2P穿透,Value为2:只用Relay转发。
范围:影响当前操作的节点对象。
PG_OPTION_PEER_RecvBacklogSize
Item: 5
说明:设置接收backlog缓冲区的长度。
格式:(Item){5}(Value){0}。Value为0:默认长度(32),Value大于0:指定缓冲区长度。
范围:影响所有的节点对象。
PG_OPTION_PEER_SendBacklogSize
Item: 6
说明:设置发送backlog缓冲区的长度。
格式:(Item){6}(Value){0}。Value为0:默认长度(32),Value大于0:指定缓冲区长度。
范围:影响所有的节点对象。
PG_OPTION_PEER_RelayList
Item: 7
说明:设置“中继转发服务器列表”。
格式:“(Item){7}(Value){” + omlEncode(“(Relay0){(Type){0}(Load){0}(Addr){127.0.0.1:443}}”) + “}”
范围:本节点生效。
PG_OPTION_PEER_ForwardSpeed
Item: 8
说明:设置“节点转发速率限制”。
格式:(Item){8}(Value){32768}。Value的值:0为禁止该节点转发,非0为允许转发的速率(单位为字节/秒)
范围:本节点生效。
PG_OPTION_PEER_ForwardGate
Item: 9
说明:设置“节点转发关闭门限”,如果该本节点自身使用的带宽超过该门限时,自动关闭节点转发,保留带宽给本节点自身使用。
格式:(Item){9}(Value){8192},Value的值,关闭转发的门限速率(单位为字节/秒)
范围:本节点生效。
PG_OPTION_PEER_ForwardTryTime
Item: 10
说明:设置“节点转发连接尝试超时时间”。
格式:(Item){10}(Value){5},Value的值为连接尝试超时时间(单位为秒)
范围:本节点生效。
PG_OPTION_PEER_ForwardUse
Item: 11
说明:设置“使用其他节点转发的标志”。
格式:(Item){11}(Value){0},Value的值:0为不使用其他节点做转发,非0为使用其他节点做转发。
范围:本节点生效。
PG_OPTION_PEER_SocketInitWnd
Item: 12
说明:设置数据传输拥塞控制滑动窗口的初始大小。
格式:(Item){12}(Value){1},Value的值:滑动窗口的初始大小(连续发送报文的个数),缺省为1。
范围:影响所有的节点对象。
PG_OPTION_PEER_SocketLoopSpeed
Item: 13
说明:设置服务器端接受客户端环回请求的速度。
格式:(Item){13}(Value){64},Value的值:每秒接受环回请求的次数,缺省为64次/秒。
范围:影响所有的节点对象。
5) P2P连接通道类型:
PG_SKT_THROUGH_Unknown
值:0
说明:未知(类型没有检测出来)
PG_SKT_THROUGH_IPV4_Pub
值:4
说明:公网IP地址
PG_SKT_THROUGH_IPV4_NATConeFull
值:5
说明:完全锥型NAT
PG_SKT_THROUGH_IPV4_NATConeHost
值:6
说明:主机限制锥型NAT
PG_SKT_THROUGH_IPV4_NATConePort
值:7
说明:端口限制锥型NAT
PG_SKT_THROUGH_IPV4_NATSymmet
值:8
说明:对称型NAT
PG_SKT_THROUGH_IPV4_Private
值:12
说明:私网直连
PG_SKT_THROUGH_IPV4_NATLoop
值:13
说明:NAT环回(Local NAT)
PG_SKT_THROUGH_IPV4_TunnelTCP
值:16
说明:TCP转发
PG_SKT_THROUGH_IPV4_TunnelHTTP
值:17
说明:HTTP转发
PG_SKT_THROUGH_IPV4_PeerForward
值:24
说明:借助第三方节点转发
PG_SKT_THROUGH_IPV6_Pub
值:32
说明:IPV6公网IP地址
PG_SKT_THROUGH_IPV6_TunnelTCP
值:40
说明:TCP V6转发
PG_SKT_THROUGH_IPV6_TunnelHTTP
值:41
说明:HTTP V6转发
PG_SKT_THROUGH_Offline
值:65535
说明:对端节点不在线
6) PG_METH_PEER_PushOption方法的选项:
PG_PEER_PUSH_OPTION_RelayList
Item: 0
说明:下发“中继转发服务器列表”给客户端节点。
格式:“(Item){0}(Value){” + omlEncode(“(Relay0){(Type){0}(Load){0}(Addr){127.0.0.1:443}}”) + “}”
范围:所操作的客户端节点生效。
PG_PEER_PUSH_OPTION_ForwardSpeed
Item: 1
说明:下发“节点转发速率限制”给客户端节点。
格式:(Item){1}(Value){32768}。Value的值:0为禁止该节点转发,非0为允许转发的速率(单位为字节/秒)
范围:所操作的客户端节点生效。
PG_PEER_PUSH_OPTION_ForwardGate
Item: 2
说明:下发“节点转发关闭门限”给客户端节点,如果该客户端节点自身使用的带宽超过该门限时,自动关闭节点转发,保留带宽给节点自身使用。
格式:(Item){2}(Value){8192},Value的值,关闭转发的门限速率(单位为字节/秒)
范围:所操作的客户端节点生效。
PG_PEER_PUSH_OPTION_ForwardTryTime
Item: 3
说明:下发“节点转发连接尝试超时时间”给客户端节点。
格式:(Item){3}(Value){5},Value的值为连接尝试超时时间(单位为秒)
范围:所操作的客户端节点生效。
PG_PEER_PUSH_OPTION_ForwardUse
Item: 4
说明:下发“使用其他节点转发的标志”给客户端节点。
格式:(Item){4}(Value){0},Value的值:0为不使用其他节点做转发,非0为使用其他节点做转发。
范围:所操作的客户端节点生效。
3. PG_CLASS_Group类:
1) 描述:
通信组类。通信组对象的成员就是节点对象的名称。
2) 选项:
PG_ADD_GROUP_Update
掩码:0x1
说明:使能PG_METH_GROUP_Update方法,允许组成员更新时通过PG_METH_GROUP_Update方法上报给应用层。
PG_ADD_GROUP_Master
掩码:0x2
说明:使能PG_METH_GROUP_Master方法,允许在组中指定Master成员。
PG_ADD_GROUP_Refered
掩码:0x4
说明:允许其他节点引用该组的成员,当该组成员更新时,自动同步到其成员节点。
PG_ADD_GROUP_NearPeer
掩码:0x8
说明:使能邻近节点功能,此选项只能与PG_ADD_GROUP_Refered选项组合使用。当组内的成很多时,一个成员节点没有必要关心所有其他成员节点,它只要知道与它相邻近的节点就可以了。被引用的组对象启用此选项后,在同步成员列表时,它只把与该成员节点相邻近的其他成员发送给该成员节点。
PG_ADD_GROUP_Modify
掩码:0x10
说明:使能PG_METH_GROUP_Modify方法,允许调用该方法修改组的成员。
PG_ADD_GROUP_Index
掩码:0x20
说明:使能用HASH表的机制索引组成员。
PG_ADD_GROUP_Offline
掩码:0x40
说明:组成员节点对象去同步时,自动离开组。
PG_ADD_GROUP_HearOnly
掩码:0x80
说明:只接收其他组成员的同步,不把本对象已经获取到的组成员信息发送给其他节点。
3) 方法:
PG_METH_GROUP_Modify
ID:32
说明:修改该组的成员
交互方式:方式7
发送请求参数:样例:(Action){0}(PeerList){(Peer1){}(Peer2){}}
Action:1为增加成员,0为删除成员。
PeerList:指定要修改的成员列表,成员名称位于OML元素的名称。成员名称就是节点对象的名称。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_GROUP_Update
ID:33
说明:该组的成员有更新时,上报给应用程序。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Action){1}(PeerList){(Peer1){}(Peer2){}}
Action:1为增加成员,0为删除成员。
PeerList:指定要修改的成员列表,成员名称位于OML元素的名称。成员名称就是节点对象的名称。
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_GROUP_Master
ID:34
交互方式:方式4
说明:指定组里的Master成员。用OnExtRequest()函数的返回值确认是否接受Master请求,返回值等于0表示接受,返回值大于0表示拒绝及其原因。
发送请求参数:样例:(Peer){NodeA}
Peer:指定的Master成员名称。
接收请求参数:样例:(Peer){NodeA}
Peer:指定的Master成员名称。
发送应答参数:无此操作
接收应答参数:无此操作
4) 扩展选项
PG_OPTION_GROUP_NearSize
Item:0
说明:设置邻近节点的范围。
格式:(Item){0}(Value){6}
范围:在需要调节邻近节点范围的“PG_CLASS_Group”类对象上操作,只影响该对象。
4. PG_CLASS_Data类:
1) 描述:
消息传输类。
2) 选项:
无
3) 方法:
PG_METH_DATA_Message
ID:32
说明:发送一个消息
交互方式:方式4
发送请求参数:任意字符串,内容和格式由用户定义
接收请求参数:同发送请求参数
发送应答参数:无此操作
接收应答参数:无此操作
5. PG_CLASS_File类:
1) 描述:
文件传输类。
2) 选项:
PG_ADD_FILE_TcpSock
掩码:0x1
说明:从TCP Socket读取数据,以及写入数据到TCP Socket。
PG_ADD_FILE_Flush
掩码:0x2
说明:将所有接收到的数据写入到文件。
PG_ADD_FILE_PeerStop
掩码:0x4
说明:文件传输的对端Peer节点去同步时,停止文件传输。
3) 方法:
PG_METH_FILE_Put
ID:32
说明:上传文件
交互方式:方式1
发送请求参数:样例:(Path){c:\temp\xxxx.txt}(PeerPath){xxxx.txt}(TimerVal){3}(Offset){0}(Size){0}
Path:文件在本地的路径(受沙盒控制)。
PeerPath:指定文件在对端的路径。如果不指定此参数,则控件从Path参数中获取文件名作为此参数。
TimerVal:自动上报文件传输状态的周期(秒),0为不自动上报文件传输状态。
Offset:传输文件的起始位置(字节)
Size:传输文件的长度。0为传输到文件的末尾。如果Offset+Size超过文件的长度时,也传输到文件的末尾。
接收请求参数:样例:(PeerPath){xxxx.txt}(Offset){0}(Size){0}
PeerPath:指定文件在对端的路径
Offset:传输文件的起始位置(字节)
Size:传输文件的长度。0为传输到文件的末尾。如果Offset+Size超过文件的长度时,也传输到文件的末尾。
发送应答参数:样例:(Path){c:\MyDoc\xxxx.txt}(TimerVal){1}
Path:文件在本地的路径(受沙盒控制)。
TimerVal:自动上报文件传输状态的周期(秒),0为不自动上报文件传输状态。
接收应答参数:空
PG_METH_FILE_Get
ID:33
说明:下载文件
交互方式:方式1
发送请求参数:样例:(Path){c:\temp\xxxx.txt}(PeerPath){xxxx.txt}(TimerVal){3}(Offset){0}(Size){0}
Path:文件在本地的路径(受沙盒控制)。
PeerPath:指定文件在对端的路径。如果不指定此参数,则控件从Path参数中获取文件名作为此参数。
TimerVal:自动上报文件传输状态的周期(秒),0为不自动上报文件传输状态。
Offset:传输文件的起始位置(字节)
Size:传输文件的长度。0为传输到文件的末尾。如果Offset+Size超过文件的长度时,也传输到文件的末尾。
接收请求参数:样例:(PeerPath){xxxx.txt}(Offset){0}(Size){0}
PeerPath:指定文件在对端的路径
Offset:传输文件的起始位置(字节)
Size:传输文件的长度。0为传输到文件的末尾。如果Offset+Size超过文件的长度时,也传输到文件的末尾。
发送应答参数:样例:(Path){c:\MyDoc\xxxx.txt}(TimerVal){1}
Path:文件在本地的路径(受沙盒控制)。
TimerVal:自动上报文件传输状态的周期(秒),0为不自动上报文件传输状态。
接收应答参数:空
PG_METH_FILE_Status
ID:34
说明:查询或上报文件传输的状态
发送请求参数:空
接收请求参数:样例:(Path){c:\temp\xxxx.txt}(PeerPath){xxxx.txt}(Speed){1056}(Status){2}(Request) {1}(Side){0}(Offset){0}(ReqSize){39946}(CurSize){27548}
Path:文件在本地的路径
PeerPath:对端文件路径
Speed:传输速率(字节/秒)
Status:文件传输的状态。1为开始传输(Start),2为正在传输(Data),3为结束传输(Stop)。
Request:请求的方法。0为GET,1为PUT
Side:传输的发送。0为接收,1为发送。
Offset:传输的起始位置(字节)
ReqSize:需要传输的总字节数
CurSize:当已经传输的字节数
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_FILE_Cancel
ID:35
说明:取消文件传输
交互方式:方式4
发送请求参数:空
接收请求参数:空
发送应答参数:无此操作
接收应答参数:无此操作
4) 常量:文件传输的状态
PG_FILE_ST_Start
ID:1
说明:开始传输
PG_FILE_ST_Data
ID:2
说明:正在传输数据
PG_FILE_ST_Stop
ID:3
说明:结束传输
6. PG_CLASS_Audio类:
1) 描述:
音频传输类。
2) 选项:
PG_ADD_AUDIO_Conference
掩码:0x1
说明:指定Audio对象为会议模式
PG_ADD_AUDIO_ShowVolume
掩码:0x2
说明:使能PG_METH_AUDIO_ShowVolume方法,实时上报输入/输出的音量变化给应用层。
PG_ADD_AUDIO_OnlyInput
掩码:0x4
说明:设置该Audio对象为只具有单向输入的音频对象。
PG_ADD_AUDIO_OnlyOutput
掩码:0x8
说明:设置该Audio对象为只具有单向输出的音频对象。用1个单向输入的音频对象与1个单向输出的音频对象,组成一条单向的音频通话会话。
PG_ADD_AUDIO_SendReliable
掩码:0x10
说明:启用可靠传输方式发送音频数据。
PG_ADD_AUDIO_NoSpeechSelf
掩码:0x20
说明:禁用本端发言。
PG_ADD_AUDIO_NoSpeechPeer
掩码:0x40
说明:禁用对端发言。
PG_ADD_AUDIO_MuteInput
掩码:0x80
说明:音频输入静音。
PG_ADD_AUDIO_MuteOutput
掩码:0x100
说明:音频输出静音。
3) 方法:
PG_METH_AUDIO_Open
ID:32
说明:打开音频传输会话
交互方式:方式1
发送请求参数:样例:(Code){0}(Mode){0}
Code:音频压缩编码:0为PCM编码,1为G.711A编码,2为AAC编码。
Mode:音频格式:0为单声道/16Bits/11025Hz采样
接收请求参数:空
发送应答参数:样例:(Code){0}(Mode){0}
Code:音频压缩编码:0为PCM编码,1为G.711A编码,2为AAC编码。
Mode:音频格式:0为单声道/16Bits/11025Hz采样
接收应答参数:空
PG_METH_AUDIO_Close
ID:33
交互方式:方式4
说明:关闭音频传输会话
发送请求参数:空
接收请求参数:空
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_AUDIO_CtrlVolume
ID:34
说明:调节或查询扬声器和麦克风的音量。当Type参数为0(扬声器)时,此操作影响当前音频对象的Peer参数指定的对象的放音音量。当Type参数为1(麦克风)时,此操作影响全局的录音音量。
交互方式:方式5
发送请求参数:样例:(Peer){}(Action){0}(Type){1}(Volume){0}(Max){0}(Min){0}
Peer:节点名。在会议模式中,当Type为0(扬声器)时指定控制哪个节点的音量;当Type为1(麦克风)时为空。在两点模式中为空。
Action:动作。0为查询音量,1为设置音量
Type:设备类型。0为扬声器,1为麦克风。
Volume:音量的值。范围:0 ~ 100
Max:最大音量(忽略)
Min:最小音量(忽略)
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Peer){}(Action){0}(Type){1}(Volume){0}(Max){100}(Min){0}
Peer:节点名。在会议模式中,当Type为0(扬声器)时指定控制哪个节点的音量;当Type为1(麦克风)时为空。在两点模式中为空。
Action:动作。0为查询音量,1为设置音量
Type:设备类型。0为扬声器,1为麦克风。
Volume:音量的值。范围:0 ~ 100
Max:最大音量
Min:最小音量
PG_METH_AUDIO_ShowVolume
ID:35
说明:实时上报输入/输出的音量变化给应用层,应用程序可以依此在界面上显示音量变化的动画。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(VolMic){0}(VolSpk){0}
VolMic:当前在麦克风上输入的音量,范围:0 ~ 100
VolSpk:当前在扬声器上输出的音量,范围:0 ~ 100
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_AUDIO_Speech
ID:36
说明:会议发言控制
交互方式:方式4
发送请求参数:样例:(Peer){NodeA}(ActSelf){1}(ActPeer){0}
Peer:指定要进行发言控制的节点
ActSelf:本端的发言状态。0为静音,1为发言
ActPeer:对端的发言状态。0为静音,1为发言
接收请求参数:样例:(Peer){NodeA}(ActSelf){0}(ActPeer){1}
Peer:指定要进行发言控制的节点
ActSelf:本端的发言状态。0为静音,1为发言
ActPeer:对端的发言状态。0为静音,1为发言
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_AUDIO_Record
ID:37
说明:录音到指定的avi、mov或mp4文件
交互方式:方式5
发送请求参数:样例:(Peer){NodeA}(Path){c:\temp\xxxx.avi}(HasVideo){0}
Peer:指定进行录音的节点
Path:存储录音的avi、mov或mp4文件路径。如果此参数为空,则停止正在进行的录音。
HasVideo:同时还需要录制视频。0为只录制音频,1为同时还录制视频。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Peer){NodeA}(Path){c:\temp\xxxx.avi}
Peer:指定进行录音的节点
Path:存储录音的avi、mov或mp4文件路径
4)扩展选项
PG_OPTION_AUDIO_MicNo
Item:1
说明:设置缺省使用的音频输入麦克风的编号,指定使用哪个麦克风。
格式:(Item){1}(Value){1}
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_MicSampleRate
Item:2
说明:设置当前使用的音频采样率。由于Peergine中间件使用的音频采样率为11K赫兹,但有些设备的音频输入不支持11K的采样率。所以,本选项给中间件指定一个设备可以支持的采样率。中间件以这个采样率采集音频数据,然后再重采样成11K。(支持Android系统)
格式:(Item){2}(Value){8000},Value为指定的采样率(Hz赫兹)。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_Detect
Item:3
说明:设置音频输入静音检测的门限。
格式:”(Item){3}(Value){“ + omlEncode(“(TailLen){20}(VolGate){50}”) + “}”, TailLen:检测的尾长(音频采集包个数),VolGate:门限电平(0 ~ 32768)。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_InputExternal
Item:4
说明:启用外部音频采集回调接口。
格式:(Item){4}(Value){1},Value的值:0为禁用,1为启用。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_OutputExternal
Item:5
说明:启用外部音频播放回调接口。
格式:(Item){5}(Value){1},Value的值:0为禁用,1为启用。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_EnableAEC
Item:6
说明:启用或禁用音频回音消除功能。
格式:(Item){6}(Value){1},Value的值:0为禁用,1为启用。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_SpeakerNo
Item:7
说明:设置缺省使用的音频播放的扬声器编号。
格式:(Item){7}(Value){0},Value的值:扬声器编号,缺省为0。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_SendReliable
Item:8
说明:启用可靠传输方法发送音频数据。
格式:(Item){8}(Value){1},Value的值:0为不可靠传输,1为可靠传输。缺省为不可靠传输。
范围:仅对当前操作的“PG_CLASS_Audio”类对象有效。
PG_OPTION_AUDIO_AttachMicNo
Item:9
说明:给音频对象绑定一个麦克风编号。音频对象将使用这个麦克风编号去打开这个麦克风设备。
格式:(Item){9}(Value){1},Value的值:麦克风编号。
范围:仅对当前操作的“PG_CLASS_Audio”类对象有效。
PG_OPTION_AUDIO_AttachSpeakerNo
Item:10
说明:给音频对象绑定一个扬声器编号。音频对象将使用这个扬声器编号去打开这个扬声器设备。
格式:(Item){10}(Value){0},Value的值:扬声器编号。
范围:仅对当前操作的“PG_CLASS_Audio”类对象有效。
PG_OPTION_AUDIO_AECMobile
Item:11
说明:启用适用于移动设备的简单回音消除。
格式:(Item){11}(Value){0},Value的值:1为简单回音消除,0为正常的回音消除。
范围:可在任何一个“PG_CLASS_Audio”类对象上操作,影响全局。
PG_OPTION_AUDIO_MuteInput
Item:12
说明:启用或禁用音频输入的静音。
格式:(Item){12}(Value){0},Value的值:1为启用,0为禁用。
范围:仅对当前操作的“PG_CLASS_Audio”类对象有效。
PG_OPTION_AUDIO_MuteOutput
Item:13
说明:启用或禁用音频输出的静音。
格式:(Item){13}(Value){0},Value的值:1为启用,0为禁用。
范围:仅对当前操作的“PG_CLASS_Audio”类对象有效。
7. PG_CLASS_Video类:
1) 描述:
视频传输类。
2) 标志:
PG_ADD_VIDEO_Conference
掩码:0x1
说明:指定该Video对象为会议模式
PG_ADD_VIDEO_Preview
掩码:0x2
说明:指定该Video对象为预览模式
PG_ADD_VIDEO_OnlyInput
掩码:0x4
说明:指定该Video对象单向输入的视频对象。
PG_ADD_VIDEO_OnlyOutput
掩码:0x8
说明:指定该Video对象单向输出的视频对象。用1个单向输入的视频对象与1个单向输出的视频对象,组成一条单向的视频通话会话。两条方向相反的单向视频通话会话,可以组成双向的视频通话,每个方向上的单向通话可以分别配置不同的视频参数。
PG_ADD_VIDEO_FrameStat
掩码:0x10
说明:启用视频帧统计信息的上报,参考“PG_METH_VIDEO_FrameStat”。
PG_ADD_VIDEO_DrawThread
掩码:0x20
说明:创建一个单独的线程来显示视频帧到视频窗口(不在UI线程里显示视频,Windows、android系统有效)。
PG_ADD_VIDEO_OutputExternal
掩码:0x40
说明:启用外部视频播放回调接口(视频解压之后)。
PG_ADD_VIDEO_OutputExtCmp
掩码:0x80
说明:启用外部视频播放回调接口(视频解压之前)。
PG_ADD_VIDEO_FilterDecode
掩码:0x100
说明:启动视频解压之后加上模糊滤镜效果。
3) 方法:
PG_METH_VIDEO_Open
ID:32
说明:打开视频传输会话
交互方式:方式1
发送请求参数:样例:(Code){0}(Mode){1}(Rate){100}(Wnd){(PosX){0}(PosY){0}(SizeX){80} (SizeY){60}(Handle){237654}}
Code:压缩编码格式。0为BMP,1为MJPEG,2为VP8,3为h264
Mode:视频捕捉的尺寸模式,参考“常量:视频捕捉的尺寸模式”章节
Rate:指定视频捕捉的帧率,每帧的时间间隔(毫秒)。
Wnd:视频的显示位置、尺寸和窗口句柄。格式为:(PosX){0}(PosY){0}(SizeX){80}(SizeY){60} (Handle){237654}
接收请求参数:空
发送应答参数:样例:(Code){0}(Mode){1}(Rate){100}(Wnd){(PosX){0}(PosY){0}(SizeX){80} (SizeY){60}(Handle){456723}}
Code:压缩编码格式。0为BMP,1为MJPEG,2为VP8,3为h264
Mode:视频捕捉的尺寸模式,参考“常量:视频捕捉的尺寸模式”章节
Rate:指定视频捕捉的帧率,每帧的时间间隔(毫秒)。
Wnd:视频的显示位置、尺寸和窗口句柄。格式为:(PosX){0}(PosY){0}(SizeX){80}(SizeY){60} (Handle){237654}
接收应答参数:空
PG_METH_VIDEO_Close
ID:33
说明:关闭视频传输会话
交互方式:方式4
发送请求参数:空
接收请求参数:空
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_VIDEO_Move
ID:34
说明:调整当前输出视频的位置和尺寸或者把当前窗口中的视频移到另外一个窗口中显示。改变坐标参数时,调整视频的位置和尺寸。改变窗口的句柄时,转移视频到另外一个窗口中显示。
交互方式:方式7
发送请求参数:样例:(Peer){NodeA}(Wnd){(PosX){0}(PosY){0}(SizeX){40}(SizeY){30} (Handle){ 237654}}
Peer:指定要进行视频调整或移动的节点。
Wnd:调整后的位置、尺寸和窗口句柄。格式为:(PosX){0}(PosY){0}(SizeX){60}(SizeY){80} (Handle){237654}
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_VIDEO_Join
ID:35
说明:加入指定节点的视频传输到会议中,此方法只能在会议模式中使用。
交互方式:方式1
发送请求参数:样例:(Peer){NodeA}(Wnd){(PosX){0}(PosY){0}(SizeX){40}(SizeY){30} (Handle){237654}}
Peer:指定要加入视频传输的节点。
Wnd:新窗口的尺寸和句柄。格式为:(PosX){0}(PosY){0}(SizeX){60}(SizeY){80} (Handle){237654}
接收请求参数:空
发送应答参数:样例:(Peer){NodeA}(Wnd){(PosX){0}(PosY){0}(SizeX){40}(SizeY){30} (Handle){237654}}
Peer:指定要加入视频传输的节点。
Wnd:新窗口的尺寸和句柄。格式为:(PosX){0}(PosY){0}(SizeX){60}(SizeY){80} (Handle){237654}
接收应答参数:空
PG_METH_VIDEO_Leave
ID:36
说明:指定节点的视频传输从会议离开,此方法只能在会议模式中使用。
交互方式:方式4
发送请求参数:样例:(Peer){NodeA}
Peer:离开操作的节点。
接收请求参数:空
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_VIDEO_Camera
ID:37
说明:抓拍指定节点视频的照片到指定的jpg文件
交互方式:方式5
发送请求参数:样例:(Peer){NodeA}(Path){d:\Pic1.jpg}
Peer:指定要对其进行拍照的节点。
Path:指定保存照片文件的路径,后缀必须为“jpg”。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Peer){NodeA}(Path){d:\Pic1.jpg}
Peer:指定要对其进行拍照的节点。
Path:指定保存照片文件的路径,后缀必须为“jpg”。
PG_METH_VIDEO_Record
ID:38
说明:录制指定节点的视频到指定的avi、mov或mp4文件。
交互方式:方式5
发送请求参数:样例:(Peer){NodeA}(Path){c:\temp\xxxx.avi}(HasAudio){0}
Peer:指定要对其进行录像的节点。
Path:指定保存avi、mov或mp4文件的路径,后缀可以为“avi”、“mov”或“mp4”。如果此参数为空,则停止正在进行的录像。
HasAudio:同时还需要录制音频。0为只录制视频,1为同时录制视频。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Peer){NodeA}(Path){c:\temp\xxxx.avi}
Peer:指定要对其进行录像的节点。
Path:指定保存avi、mov或mp4文件的路径,后缀必须为可以为“avi”、“mov”或“mp4”。
PG_METH_VIDEO_Transfer
ID:39
说明:暂停或者继续视频发送。
交互方式:方式7
发送请求参数:样例:(Peer){NodeA}(Local){1}(Remote){0}
Peer:指定要对其视频发送控制的节点。
Local:本端视频的控制。1为允许发送,0为暂停发送
Remote:对端视频的控制。1为允许发送,0为暂停发送
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_VIDEO_FrameStat
ID:40
说明:上报视频发送状态的统计信息。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Peer){NodeA}(Total){2365}(Drop){0}
Peer:指定上报视频统计的节点。
Total:总发送的视频帧数
Drop:丢弃的视频帧数
发送应答参数:无此操作
接收应答参数:无此操作。
4) 常量:视频捕捉的尺寸模式
PG_VIDEO_MODE_80x60
ID:0
说明:80 x 60像素
PG_VIDEO_MODE_160x120
ID:1
说明:160 x 120像素
PG_VIDEO_MODE_320x240
ID:2
说明:320 x 240像素
PG_VIDEO_MODE_640x480
ID:3
说明:640 x 480像素
PG_VIDEO_MODE_800x600
ID:4
说明:800 x 600像素
PG_VIDEO_MODE_1024x768
ID:5
说明:1024 x 768像素
PG_VIDEO_MODE_176x144
ID:6
说明:176×144像素
PG_VIDEO_MODE_352x288
ID:7
说明:352×288像素
PG_VIDEO_MODE_704x576
ID:8
说明:704×576像素
PG_VIDEO_MODE_854x480
ID:9
说明:854×480像素
PG_VIDEO_MODE_1280x720
ID:10
说明:1280×720像素
PG_VIDEO_MODE_1920x1080
ID:11
说明:1920×1080像素
5)扩展选项
PG_OPTION_VIDEO_CameraNo
Item:0
说明:设置当前使用的摄像头编号,指定使用哪个摄像头(前置、后置,或者摄像头编号)。
格式:(Item){0}(Value){1}
范围:可在任何一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_CameraFormat
Item:1
说明:有些Android设备上,调用Android API查询到的视频格式与实际采集到的视频格式是不一样的。这将导致中间件不能正确处理视频。这个选项告诉中间件实际采集到的视频的格式,替代用Android API查询到的视频格式,使中间件能正确处理视频。(支持Android系统)
格式:(Item){1}(Value){1},Value的值指定了视频格式的编号:1为YVYU、2为YUYV、3为YUV420SP、4为YUV422SP、5为I420、6为YV12。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_CameraRotate
Item:2
说明:在Android设备上纵向采集视频时,图像确实是纵向采集的。但图像却是横向保存在内存里的,需要在内存里做一次90度的图像旋转,图像显示时才是纵向的。(支持Android、IOS系统)
格式:(Item){2}(Value){90},Value的值指定了旋转的角度。支持90、180和270。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_CameraConvert
Item:3
说明:由于中间件只规定了几种常见的视频图像尺寸,只有规定的尺寸中间件才能处理。但是Android上视频采集摄像头的规格多种多样,五花八门,有些Android平板上可以外接USB摄像头,情况就更复杂了。所以,当中间件所规定的尺寸摄像头都不支持时,视频采集将失败。通过这个扩展选项,告诉中间件一个摄像头能够支持的尺寸,让中间件使用这个尺寸去初始化摄像头,采集出视频后,再将图像转换成中间件规定的尺寸,问题就解决了。(支持Android系统)
格式:“(Item){3}(Value){” + Node.omlEncode(“(Mode){1}(Width){380}(Height) {260}”) + “}”,其中Mode为中间件规定的尺寸模式(参考“常量:视频捕捉的尺寸模式” ), Width和Height为摄像头实际支持的采集尺寸。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_CameraRate
Item:4
说明:设置摄像头的采集帧率。
格式:(Item){4}(Value){40},Value的值为每帧的间隔(毫秒)。例如:1000 / 40 = 25帧/秒。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_ParamCommon
Item:5
说明:设置通用的视频编码相关参数。(其中参数BitRate、KeyFrmRate和LossAllow只对VP8和H264视频编码有效)。
格式:“(Item){5}(Value){” + Node.omlEncode(“(BitRate){512}(FrmRate){40}(KeyFrmRate){3000} (LossAllow){0}”) + “}”。BitRate 为码率(Kbps,默认为512)。FrmRate 为帧率(帧间时间间隔,毫秒,默认为40)。KeyFrmRate 为I帧率(I帧间时间间隔,毫秒,默认为3000)。LossAllow为播放时允许连续丢帧数(缺省为0,允许丢帧会产生花屏)。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_ParamCodeMode
Item:6
说明:为每种视频编码和尺寸设置视频编码相关参数。当此参数不为0时,使用此参数,否则使用通用的视频编码相关参数。
格式:“(Item){5}(Value){” + Node.omlEncode(“(Code){3}(Mode){2}(BitRate){0}(FrmRate){0} (KeyFrmRate){0}(LossAllow){0}”) + “}”。 Code为编码类型(1为MJPEG,2为VP8,3为h264)。Mode为图像尺寸模式(参考“常量:视频捕捉的尺寸模式”)。BitRate、FrmRate、KeyFrmRate和LossAllow的格式参考通用的视频编码相关参数。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_JitterDelay
Item:7
说明:设置消除网络传输抖动的延时时间。
格式:(Item){7}(Value){500},Value的值为消抖延时的时间(毫秒)。缺省为300毫秒。
范围:在需要调整消抖时延的“PG_CLASS_Video”类对象上操作,只影响该对象。
PG_OPTION_VIDEO_InputExternal
Item:8
说明:开启视频数据的外部输入接口。启用以后应用程序在中间件外部采集压缩视频数据,然后通过API输入到中间件中。
格式:(Item){8}(Value){1},Value的值:0为禁用,1为启用。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_CameraEnable
Item:9
说明:临时禁用和启用摄像头。
格式:(Item){9}(Value){1},Value的值:0为禁用,1为启用。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_FillMode
Item:10
说明:设置视频输出匹配窗口的模式。
格式:(Item){10}(Value){0},Value的值: 0为剪裁,1为整幅,2为拉伸。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_OutputExternal
Item:11
说明:启用外部视频播放回调接口(视频解压之后)。
格式:(Item){11}(Value){0},Value的值:0为禁用,1为启用。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_RedefModeSize
Item:12
说明:修改指定分辨率模式的宽度和高度。
格式:“(Item){12}(Value){” + Node.omlEncode(“(Mode){2}(Width){480}(Height){640}”) + “}”,Value的值:Mode:需要修改分辨率的模式,Width:新的宽度,Height:新的高度。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。重要:修改分辨率模式的宽度和高度,必须在打开第一个视频对象之前修改才有效。
PG_OPTION_VIDEO_OutputExtCmp
Item:13
说明:启用外部视频播放回调接口(视频解压之前)。
格式:(Item){10}(Value){0},Value的值: 0为禁用,1为启用。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_FlashLight
Item:14
说明:打开或关闭摄像头闪光灯(对android系统后置摄像头有效)。
格式:(Item){14}(Value){0},Value的值: 0为关闭闪光灯,1为打开闪光灯。
范围:可在任意一个“PG_CLASS_Video”类对象上操作,影响全局。
PG_OPTION_VIDEO_AttachCameraNo
Item:15
说明:给视频对象绑定一个摄像头编号,该视频对象使用该摄像头采集的视频源。
格式:(Item){15}(Value){0},Value的值: 摄像头编号0、1、2、3、……。
范围:仅对操作的“PG_CLASS_Video”类对象有效。
6) Android视频采集扩展选项说明
由于在Android上的视频采集场景比较多样,Peergine中间件提供扩展选项设置接口,通过PG_METH_COMMON_SetOption方法设置视频采集的参数,以适应多种视频采集的场景。
Android上设置视频采集选项的原因一般有以下两个方面:
- 正常使用需要:选择前置/后置摄像头,指定横屏/纵屏采集视频。
- 弥补设备的缺陷:有些小厂商开发的Android平板或手机的设备驱动程序适配不完整或者不正确,导致调用Android API无法正确访问设备。需要中间件做一个转换适配层后,才能正确使用。
使用扩站选项设置视频采集参数的时机是:PG_CLASS_Video类型的对象生命周期的任何时候。参考例程(Java):
// P2P 节点Node添加一个PG_CLASS_Video类型的对象“Video1”
Node.ObjectAdd(“Video1”, “PG_CLASS_Video, “”, 0);
// 调用PG_METH_COMMON_SetOption方法,设置扩展选型,旋转图像90度
Node.ObjectRequest(“Video1”, 2, “(Item){2}(Value){90}”, “”);
// 删除对象
Node.ObjectDelete(“Video1”);
8. PG_CLASS_Board类:
1) 描述:
白板共享类。
2) 选项:
无
3) 方法:
PG_METH_BOARD_Open
ID:32
说明:打开一个白板共享对象。
交互方式:方式7
发送请求参数:样例:(Wnd){3664687}
Wnd:白板窗口的句柄
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_BOARD_Close
ID:33
说明:关闭一个白板共享对象。
交互方式:方式7
发送请求参数:空
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_BOARD_Shape
ID:34
说明:设置绘图的参数。
交互方式:方式7
发送请求参数:样例:(Shape){1}(Color){223344}(Width){3}(Type){0}
Shape:图形的类型。参考“常量:图形的类型”章节
Color:线条的颜色,RGB格式。
Width:线条的宽度(像素)
Type:线条的风格(未实现)
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_BOARD_Cursor
ID:35
说明:设置不同图形的鼠标光标。
交互方式:方式7
发送请求参数:样例:(Shape){1}(Path){c:\temp\pen.cur}
Shape:图形的类型。参考“常量:图形的类型”章节
Path:光标文件的路径,文件名的后缀必须为“.cur”。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_BOARD_Save
ID:36
说明:保存白板上所写画的内容到图片里。
交互方式:方式5
发送请求参数:样例:(Path){c:\temp\xxxx.png}
Path:保存白板的图片文件路径,后缀必须为“png”。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Path){c:\temp\xxxx.png}
Path:保存白板的图片文件路径,后缀必须为“png”。
PG_METH_BOARD_Load
ID:37
说明:从文件打开一个图片显示在白板上。
交互方式:方式5
发送请求参数:样例:(Path){c:\temp\xxxx.png}
Path:打开的图片文件路径,后缀必须为“png”。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Path){c:\temp\xxxx.png}
Path:打开的图片文件路径,后缀必须为“png”。
4) 常量:图形的类型
PG_BOARD_SHAPE_Null
ID:0
说明:取消绘图状态
PG_BOARD_SHAPE_Pen
ID:1
说明:绘制任意线条
PG_BOARD_SHAPE_Line
ID:2
说明:绘制直线
PG_BOARD_SHAPE_Rectangle
ID:3
说明:绘制矩形
PG_BOARD_SHAPE_Ellipse
ID:4
说明:绘制椭圆
PG_BOARD_SHAPE_Pointer
ID:5
说明:绘制指针。当一个节点上的鼠标移动时,在其他节点上绘制同步移动的指针。
1) 描述:
文件分块共享类。
2) 选项:
PG_ADD_SHARE_Distribute
掩码:0x1
说明:使能分散传输模式。此选项没有使能时,控件缺省以从前到后的顺序获取文件的数据块。但此选项使能后,控件尽力避免按照从前到后的顺序来获取文件的数据块。
3) 方法:
PG_METH_SHARE_Open
ID:32
说明:打开文件分块共享对象。
交互方式:方式7
发送请求参数:样例:(Path){c:\temp\xxxxx.avi}(HttpURL){}(Hash){}(FileSize){}(BlockSize){0} (TimerVal){3}
Path:共享文件的存储路径(受沙盒控制)。
HttpURL:共享文件数据实时转发到本地HTTP服务器时的URI。如果不需要转发到本地HTTP服务器,则此参数为空。
Hash:共享文件的摘要,SHA256算法生成,Base64格式。如果本节点已经获取到完整的文件,则作为共享的种子,这时不需要指定文件的摘要,此参数为空。
FileSize:共享文件的长度(字节)。如果本节点已经获取到完整的文件,则作为共享的种子,这时不需要指定文件的长度,此参数为空。
BlockSize:文件分块传输的块大小(字节)。如果此参数为0,则块的大小为缺省的1M字节。
TimerVal:周期自动上报文件传输状态的时间间隔(秒)。如果不需要自动上报文件传输状态,则此参数为0。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_SHARE_Close
ID:33
说明:关闭文件分块共享对象。
交互方式:方式7
发送请求参数:空
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_SHARE_FileInfo
ID:34
说明:获取共享文件的信息。
发送请求参数:空
接收请求参数:样例:(Name){xxxx.avi}(Hash){}(FileSize){564564}(CurSize){89879}(IsSeed){1}
Name:共享文件名。
Hash:共享文件的摘要,SHA256算法生成,Base64格式。
FileSize:共享文件的长度(字节)。
CurSize:当前已经传输的长度(字节)
IsSeed:本节点是否为共享种子。当本节点获取到完整的文件时,就成为共享种子。0为不是种子,1为是种子。
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_SHARE_FileStatus
ID:35
说明:获取共享文件的传输状态。
发送请求参数:空
接收请求参数:样例:(Path){}(Hash){}(FileSize){564564}(CurSize){3378}(Speed){3433}(BlockNum) {27}(BlockSta)(0-2){1}(3-26){0}}
Path:文件的路径
Hash:文件的摘要
FileSize:共享文件的总长度(字节)
CurSize:当前已经传输的长度(字节)
Speed:当前传输的速度(字节/秒)
BlockNum:共享文件的总的块数目
BlockSta:数据块的状态。通过一个OML列表来表示数据块的状态,OML元素的名称是数据块的序号,OML元素的内容是数据块的状态。如果多个连续的数据块的状态相同,合并到一个OML元素中,元素名由这些连续数据块的起始块号和终止块号组成,中间用‘-’号连接。例如:(0-2){1}。状态值参考“常量:数据块的状态”章节。
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_SHARE_PeerStatus
ID:36
说明:获取共享文件的源节点的数据块传输状态。
交互方式:方式6
发送请求参数:样例:(Peer){NodeA}(Index){0}
Peer:指定获取数据块状态的源节点名称。如果此参数不为空,则忽略下文的Index参数。
Index:指定获取数据块状态的源节点序号。上文的Peer参数为空时,使用此参数。通过依次递增序号,可以遍历所有源节点的数据块状态。
接收请求参数:样例:(Peer){NodeA}(SendSpeed){8983}(RecvSpeed){2325}(SendBytes){565009} (RecvBytes){1767}(BlockNum){27}(BlockSta){(0-2){1}(3-26){0}}
Peer:原节点的名称
SendSpeed:发送速率(字节/秒)
RecvSpeed:接收速率(字节/秒)
SendBytes:已发送的字节
RecvBytes:已接收的字节
BlockNum:总的数据块数目
BlockSta:数据块的状态。
发送应答参数:无此操作
接收应答参数:无此操作
4) 常量:数据块的状态
PG_SHARE_BLOCK_ST_Empty
ID:0
说明:该数据块还没有源。
PG_SHARE_BLOCK_ST_Source
ID:1
说明:该数据块已经找到源,但还没有开始传输。
PG_SHARE_BLOCK_ST_Getting
ID:2
说明:该数据块正在传输。
PG_SHARE_BLOCK_ST_Stored
ID:3
说明:该数据块已经获取完成并存储到本地的文件中。
10. PG_CLASS_Table类:
1) 描述:
数据表传输类
2) 选项:
PG_ADD_TABLE_Master
掩码:0x1
说明:使能能主节点模式,只有主节点可以插入或修改,其他节点只能查询。(此功能未实现)
PG_ADD_TABLE_File
掩码:0x2
说明:使能文件传输模式,数据表的每条记录用来同步一个文件。参考“说明:文件传输模式”章节。
3) 方法:
PG_METH_TABLE_Init
ID:32
说明:初始化数据表。
交互方式:方式7
发送请求参数:样例:(MaxRec){256}(FldSize){6}(Param){}
MaxRec:数据表的最大记录数,范围:1 ~ 65534。
FldSize:数据表的字段数,范围1 ~ 32。
Param:参数,不能包含OML标记字符,请用omlEncode()进行编码。使能文件传输模式时,通过此参数传递文件缓冲的目录路径。参考“说明:文件传输模式”章节。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Sync
ID:33
说明:强制同步数据表。
交互方式:方式7
发送请求参数:样例:(Action){1}(Param){}
Action:同步的动作,参考“常量:强制同步动作”
Param:同步的参数。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Index
ID:34
说明:在指定的字段上建立数据表的索引。
交互方式:方式7
发送请求参数:样例:(SortMode){1}(FieldID){0}
SortMode:排序方式。0为降序,1为升序
FieldID:建立索引的字段ID
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Insert
ID:35
说明:在数据表中插入一条记录
交互方式:方式7
发送请求参数:样例:(ValList){(0){aaaa}(1){bbb}(2){ccccccc}}
ValList:记录的各字段的值列表。格式为:(字段ID){字段的值}
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Delete
ID:36
说明:从数据表中删除一条或多条记录。
交互方式:方式7
发送请求参数:样例:(RecID){0}(RecSize){1}(Cond){(Operator){0}(FieldID){0}(Value){aaaa}}”
RecID:匹配记录的起始记录ID
RecSize:指定删除记录的条数
Cond:匹配记录的条件。Operator为比较操作符,FieldID为比较的字段ID,Value为比较的值。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Update
ID:37
说明:修改一条记录的字段值。
交互方式:方式7
发送请求参数:样例:(RecID){0}(Cond){(Operator){0}(FieldID){0}(Value){aaaa}}(ValList){(0){xxx}}
RecID:匹配记录的起始记录ID
Cond:匹配记录的条件。Operator为比较操作符,FieldID为比较的字段ID,Value为比较的值。
ValList:记录的各字段的值列表
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Query
ID:38
说明:查询数据表。查询之后通过PG_METH_TABLE_Report方法上报查询结果。
交互方式:方式7
发送请求参数:样例:(RecID){0}(RecSize){3}(Cond){(Operator){0}(FieldID){0}(Value){aaabbb}} (FldIDList){(0)(1)(2)}”
RecID:匹配记录的起始记录ID
RecSize:指定查询记录的条数
Cond:匹配记录的条件。Operator为比较操作符,FieldID为比较的字段ID,Value为比较的值。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Report
ID:39
说明:上报记录数据变化或查询结果给应用层。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(RecID){1}(TopID){10}(NextID){1}(Action){1}(ValSize){2}(ValList){(0){xxx} (1){aaaa}}
RecID:当前记录的ID
TopID:最大的记录ID
NextID:下一个记录的ID
Action:对记录的操作。1为记录被添加或修改,0为记录被删除。
ValSize:上报的字段数目
ValList:上报的字段值列表
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Import
ID:40
说明:从指定的数据源导入数据倒数据表(未实现)。
交互方式:方式8
发送请求参数:样例:(Type){0}(Path){c:\peergine\tab1.pgtab}
Type:数据源的类型。0为*.pgtab文件。
Path:数据源的路径(受沙盒控制)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_TABLE_Export
ID:41
说明:把数据表的内容导出或保存到数据源中(未实现)。
交互方式:方式8
发送请求参数:样例:(Type){0}(Path){c:\peergine\tab1.pgtab}
Type:数据源的类型。0为*.pgtab文件。
Path:数据源的路径(受沙盒控制)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
4) 常量:强制同步的动作
PG_TABLE_SYNC_ACT_Request
ID:0
说明:立即执行一个同步请求操作。
PG_TABLE_SYNC_ACT_Hole
ID:1
说明:强制跳过同步的记录空洞。如果数据表中某些记录已经没有源(添加这些记录的节点已经不在通信组里了),则数据表的同步操作就会停止在这些记录上,不能再继续传输数据,这种情况称为记录空洞(Hole)。执行此动作可以跳过这些没有源的记录继续同步后面有源的记录。
5) 常量:比较操作符
PG_TABLE_OPTR_Equal
ID:0
说明:相等
PG_TABLE_OPTR_Less
ID:1
说明:小于
PG_TABLE_OPTR_More
ID:2
说明:大于
PG_TABLE_OPTR_UnEqual
ID:3
说明:不相等
PG_TABLE_OPTR_LessEqual
ID:4
说明:小于等于
PG_TABLE_OPTR_MoreEqual
ID:5
说明:大于等于
PG_TABLE_OPTR_Prefix
ID:6
说明:匹配前缀
PG_TABLE_OPTR_Suffix
ID:7
说明:匹配后缀
PG_TABLE_OPTR_Include
ID:8
说明:包含子串
6) 说明:文件传输模式
对等数据表支持传输文件功能,在创建数据表对象时通过PG_ADD_TABLE_File选项来使能。使能文件传输模式后,PG_METH_TABLE_Init方法的Param参数用来传递文件缓冲区的名称,该参数为OML格式,样例为:(Cache){MyFileCache}。文件缓冲区用CacheSetDir命令来开启。由于该参数为OML格式,包含OML标记字符,所以要用omlEncode()函数来编码。代码示例(JavaScript)如下:
pgAtx.utilCmd(“CacheSetDir”, “(Name){MyFileCache}(Dir){c:\\Peergine\\FileCache}”);
var sParam = “(Cache){MyFileCache}”;
var sInEle = “(MaxRec){1024}(FldSize){8}(Param){“ + pgAtx.omlEncode(sParam) + “}”;
pgAtx.ObjectRequest(“Table1”, 32, sInEle, “TableInit”);
在文件传输模式时,数据表的每一条记录存储一个文件的属性,文件的属性存储在前6个字段里。文件属性与字段ID的对应分别为:
0:URL,文件在缓冲区中的唯一标识。
1:Path,文件在缓冲区中的存储路径。
2:Size,文件的长度(字节)。
3:Time,文件的修改时间。格式:YYYY-MM-DD,HH:MM:SS
4:Hash,文件的摘要。SHA256算法生成,Base64格式。
5:Status,文件的传输状态。参考“常量:文件传输的状态”章节。
这些文件属性发生变化时,会通过PG_METH_TABLE_Report方法上报给应用层。
在文件传输模式初始化数据表时,如果指定的FldSize小于6,则控件会强制使FldSize等于6。如果FldSize大于6,则ID大于等于6的字段的用法由应用层定义。
11. PG_CLASS_Live类:
1) 描述:
媒体流直播类。
2) 选项:
PG_ADD_LIVE_NoOutput
掩码:0x1
说明:收到媒体流后只进行转发,不进行输出、播放。
PG_ADD_LIVE_LoadFirst
掩码:0x2
说明:优先从剩余转发负荷最大的节点获取媒体流。
PG_ADD_LIVE_DrawThread
掩码:0x4
说明:创建一个单独的线程来显示视频帧到视频窗口(不在UI线程里显示视频,Windows、android系统有效)。
PG_ADD_LIVE_FrameStat
掩码:0x8
说明:启用视频帧统计信息的上报,参考“PG_METH_LIVE_FrameStat”。
PG_ADD_LIVE_FilterDecode
掩码:0x10
说明:启动视频解压之后加上模糊滤镜效果。
3) 方法:
PG_METH_LIVE_Open
ID:32
说明:打开一个媒体流直播对象。
交互方式:方式7
发送请求参数:样例:(Source){1}(Media){1}(Delay){3000}(CacheSize){256}(MaxPart){1} (TimerVal){3}(Param){}
Source:指定本节点是否为源节点。1为源(播放)节点,0为收看节点。
Media:指定媒体流的类型。参考“常量:媒体流的类型”章节
Delay:接收媒体流的缓冲延时时间(毫秒)。只有作为源节点时,才需要指定此参数。
CacheSize:缓冲区的长度(帧数)。只有作为源节点时,才需要指定此参数。
MaxPart:最大的子流数目。控件支持获取媒体流时,分裂成多个子流分别从不同的源节点获取。此参数指定最大的子流数目。此参数的值必须为以2为底数、正整数为指数的幂,例如:1、2、4、8等。
TimerVal:周期自动上报传输状态的时间间隔。如果此参数为0,则不自动上报状态。
Param:初始化媒体流的参数。此参数中不能包含OML的标记字符,请用omlEncode()进行编码。参考“说明:媒体流的初始化”章节。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_LIVE_Close
ID:33
说明:关闭一个媒体流直播对象
交互方式:方式7
发送请求参数:空
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_LIVE_Ctrl
ID:34
说明:控制媒体流的播放和收看。
交互方式:方式7
发送请求参数:样例:(Action){1}(Param){0}
Action:控制动作。参考“常量:媒体流的控制动作”章节
Param:控制参数(未使用)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_LIVE_Status
ID:35
说明:获取或上报媒体流传输的状态。
发送请求参数:空
接收请求参数:样例:(BitRate){84950}(FrmRate){9}(FrmPlay){456}(FrmCache){568}(FrmTotal){0}
BitRate:媒体流的比特率(bits/秒)
FrmRate:媒体流的帧率(帧/秒)
FrmPlay:已经播放的帧号
FrmCache:已经缓冲的帧号
FrmTotal:总的帧数
发送应答参数:无此操作
接收应答参数:无此操作
PG_METH_LIVE_Record
ID:36
说明:录制媒体流到avi、mov或mp4文件中。只有作为收看节点时,才能录制。
交互方式:方式5
发送请求参数:样例:(Path){c:\temp\xxxx.avi}(HasVideo){0}(HasAudio){0}
Path:avi、mov或mp4文件的路径(受沙盒控制),文件名后缀可以为“avi”、“mov”或“mp4”。
HasVideo:需要录制视频。0为不需要录制视频,1为需要录制视频。
HasAudio:需要录制音频。0为不需要录制音频,1为需要录制音频。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Path){c:\temp\xxxx.avi}
Path:avi、mov或mp4文件的路径。
PG_METH_LIVE_Camera
ID:37
说明:拍摄视频快照。
交互方式:方式5
发送请求参数:样例:(Path){c:\temp\xxxx.jpg}
Path:jpg文件的路径(受沙盒控制),文件名后缀必须为“jpg”(大小写不敏感)。
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(Path){c:\temp\xxxx.jpg}
Path:jpg文件的路径。
PG_METH_LIVE_RelayPeer
ID:38
说明:强制从指定的节点获取媒体流。
交互方式:方式5
发送请求参数:样例:(Flag){0}(Action){1}(Peer){abc}
Flag:标志。1为返回当前的节点列表,0为不返回节点列表。
Action:操作。1为增加,0为删除。
Peer:指定获取媒体流的节点名称
接收请求参数:无此操作
发送应答参数:无此操作
接收应答参数:样例:(PeerSize){2}(PeerList){(abc){}(xyx){}}
PeerSize:节点个数。
PeerList:节点列表。
PG_METH_LIVE_FrameStat
ID:39
说明:上报视频发送状态的统计信息。
交互方式:方式8
发送请求参数:无此操作
接收请求参数:样例:(Peer){NodeA}(Total){2365}(Drop){0}
Peer:指定上报视频统计的节点。
Total:总发送的视频帧数
Drop:丢弃的视频帧数
发送应答参数:无此操作
接收应答参数:无此操作。
4) 常量:媒体流的类型
PG_LIVE_MEDIA_Audio
ID:0
说明:实时捕捉的音频流。
PG_LIVE_MEDIA_Video
ID:1
说明:实时捕捉的视频流。
PG_LIVE_MEDIA_AVI
ID:2
说明:播放AVI文件。控件目前支持的AVI视频/音频格式为:
音频:PCM或G.711A编码、16bit采样、采样速率11 KHz、单通道。
视频:MJPEG(A)、VP8视频压缩格式。
如果你的AVI文件格式不符合,请先用工具转换成以上的格式后再播放。
5) 常量:媒体流的控制动作
PG_LIVE_CTRL_Stop
ID:0
说明:停止播放或收看
PG_LIVE_CTRL_Play
ID:1
说明:开始播放或收看
PG_LIVE_CTRL_Pause
ID:2
说明:暂停播放或收看(未实现)
PG_LIVE_CTRL_Position
ID:3
说明:跳到指定位置进行播放或收看(未实现)。
PG_LIVE_CTRL_JpegPull
ID:4
说明:直播使用MJPEG的视频编码格式时,如果帧率设置得很低,但又想立即看到最新的图像,则可以调用此操作,让中间件立即发送一帧图像。
6) 说明:媒体流的初始化
实时音频流的初始化
源节点的Param参数:样例:(Code){0}(Mode){0}
Code:音频压缩编码:0为PCM编码,1为G.711A编码。
Mode:音频格式:0为单声道/16Bits/11K采样
收听节点的Param参数:空(不需要参数)
实时视频流的初始化
源节点的Param参数:样例:(Code){1}(Mode){1}(Rate){100}
Code:视频压缩编码。0为BMP,1为MJPEG,2为VP8。
Mode:视频捕捉的尺寸模式。参考“常量:视频捕捉的尺寸模式”章节。
Rate:视频帧率,每帧的时间间隔(毫秒)。
收看节点的Param参数:样例:(Wnd){(PosX){0}(PosY){0}(SizeX){80}(SizeY){60}(Handle){2376}}
Wnd:显示视频的窗口的尺寸和句柄。
播放AVI文件的初始化
源节点的Param参数:样例:(Path){d:\temp\xxxx.avi}
Path:AVI文件的路径(受沙盒控制)。
收看节点的Param参数:样例:(Wnd){(PosX){0}(PosY){0}(SizeX){80}(SizeY){60}(Handle){7654}}
Wnd:显示视频的窗口的尺寸和句柄。
7)扩展选项
PG_OPTION_LIVE_RelayNum
Item:0
说明:允许把媒体流同时转发给下一级节点的个数。
格式:(Item){0}(Value){2}
范围:影响当前的直播类对象。
PG_OPTION_LIVE_NearSize
Item:1
说明:设置邻近节点的个数。直播对象只与邻近节点交换状态信息,只从邻近节点获取媒体流。
格式:(Item){1}(Value){8}
范围:影响当前的直播类对象。
PG_OPTION_LIVE_AttachCameraNo
Item:2
说明:给直播对象绑定一个摄像头编号,该直播对象使用该摄像头采集的视频源。
格式:(Item){2}(Value){0},Value的值: 摄像头编号0、1、2、3、……
范围:影响当前的直播类对象。
对象标记语言(OML)
1. 语法说明
OML(对象标记语言,Object Markup Language)是Peergine中数据传递、数据存储和数据配置的通用数据表达格式。Peergine提供了OML解析器功能辅助生成和解析OML文本,请参考“控件的OML解析器函数”章节。
OML的标记字符为:’(’、’)’、’[’、’]’、’{’、’}’、’&’共7个ASCII字符。
OML描述的数据元素称为对象。由’(’和’)’之间的字符串称为对象的名称,由’[’和’]’之间的字符串称为对象的类型,由’{’和’}’之间的字符串为对象的内容或子对象。一个对象由名称、类型和内容(或子对象)构成。
OML的转义字符为’&’。
‘(‘ 转义为 &A,‘)‘ 转义为 &B,‘[‘ 转义为 &C,‘]‘ 转义为 &D,‘{‘ 转义为 &E,‘}‘ 转义为 &F,‘&‘ 转义为 &G。
2. 样例
1) 简单OML对象(没有包含子对象):
(LiMing)[student]{XX学校的学生}
2) 复合OML对象(包含子对象):
(LiMing)[student]{
(Name)[string]{李明}
(Sex)[bool]{男}
(Age)[int]{12}
(Comment)[string]{XX学校的学生}
}
附录1:样例程序
1. 简单聊天室(详细注释)
1) 说明
此演示程序实现多人之间的文本和音频聊天功能。服务器端代码文件为chatsvr.js,在Windows Script Host (cscript.exe)中运行。客户端代码文件为chatclt.htm,在Internet Explorer中运行。可在同一台计算机上运行一个服务器端和多个客户端,模拟多人聊天。
2) 服务器程序
服务器端代码清单如下。把以下代码保存到chatsvr.js文件中,并在控制台中用cscript chatsvr.js命令执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
/**************************************************** chatsvr.js *****************************************************/ var pgAtx = null; var s_sServer = "PGServer"; // 服务器节点对象的名称 var s_sOnline = "PGOnline"; // 用户在线状态的通信组对象名称。 var s_uMethCmnButt = 32; // 类方法ID的起始值 function pgOutString(sOut) { WScript.Echo(sOut); } var pgMain = { Login:function(sData, uHandle, sPeer) { // 用户的登录请求,在这里验证用户的账号信息 // ... // 发送登录应答。 var sData = "(Expire){30}(Type){0}(Sess){}(Param){}"; pgAtx.ObjectExtReply(s_sServer, 0, sData, uHandle); return -1; }, Logout:function(sData) { // 用户注销登录。 var sUser = pgAtx.omlGetContent(sData, "User"); if (sUser != "") { // 从在线用户通信组中删除用户成员。 pgAtx.ObjectRequest(s_sOnline, (s_uMethCmnButt + 0), "(Action){0}(PeerList){(" + sUser + "){}}", "DeleteUser"); } return 0; }, UpdateUser:function(sData) { // 用上线/下线通知。 var uAct = pgAtx.omlGetContent(sData, "Action"); var sPeerList = pgAtx.omlGetName(sData, "PeerList"); if (sPeerList) { var iInd = 0; while (1) { var sItem = pgAtx.omlGetEle(sData, "PeerList.", 1, iInd); if (sItem == "") { break; } var sUser = pgAtx.omlGetName(sItem, ""); if (uAct != 0) { // 上线 pgOutString("ADD ONLINE USER: " + sUser); } else { // 下线 pgOutString("DELETE ONLINE USER: " + sUser); } iInd++; } } return 0; } } function pgOnExtRequest(sObj, uMeth, sData, uHandle, sPeer) { // 接收请求的回调函数。 if (sObj == s_sServer) { if (uMeth == (s_uMethCmnButt + 0)) { return pgMain.Login(sData, uHandle, sPeer); } if (uMeth == (s_uMethCmnButt + 1)) { return pgMain.Logout(sData); } return 0; } if (sObj == s_sOnline) { if (uMeth == (s_uMethCmnButt + 1)) { pgMain.UpdateUser(sData); } return 0; } return 0; } function pgOnReply(sObj, uErr, sData, sParam) { // 接收应答的回调函数。 return 1; } function pgInitialize() { // 创建控件实例。 pgAtx = new ActiveXObject("pgATX.pgATXCtrl"); if (!pgAtx) { pgOutString("Create pgAtx failed"); return false; } // 配置控件参数。 pgAtx.Control = "Type=1"; // 启用节点功能。 pgAtx.Node = "Type=1;Cert=peergine_localhost.pgcert"; // 设置为登录服务器节点。 pgAtx.Class = ""; // 不需要启用任何功能类。 pgAtx.Local = "Name=" + s_sServer + ";Addr=0:0:0:127.0.0.1:10002:0"; // 设置服务器节名称和地址。 pgAtx.OnExtRequest = pgOnExtRequest; // 指定接收请求的回调函数。 pgAtx.OnReply = pgOnReply; // 指定接收应答的回调函数。 if (!pgAtx.Start(0)) { // 启动节点功能。 pgOutString("Initialize failed"); return false; } // 创建控制在线用户状态的通信组对象。 // 启用选项:PG_ADD_GROUP_Update=0x1,允许输出上线/下线通知。 // 启用选项:PG_ADD_GROUP_Refered=0x4,允许其他节点引用此通信组成员。 // 启用选项:PG_ADD_GROUP_Modify=0x10,允许调用API增加/删除通信组的成员。 if (!pgAtx.ObjectAdd(s_sOnline, "PG_CLASS_Group", "", (0x10 | 0x4 | 0x1))) { pgOutString("Add 'Online' object failed"); return false; } // 初始化成功。 pgOutString("Peergine server start success"); return true; } function pgClean() { // 删除通信组对象。 pgAtx.ObjectDelete(s_sOnline); } function pgMainFunc() { // 初始化程序 if (!pgInitialize()) { return; } // 处理消息循环。 while (pgAtx.PumpMessage(0)) { ; } // 清理。 pgClean(); } // 调用主函数。 pgMainFunc(); |
客户端代码清单。保存以下代码到chatclt.htm文件,并在Internet Explorer中运行。3) 客户端程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
<!--chatclt.htm--> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>简单聊天室演示</title> <style> body,td{ font-size:12px; } .txt{ font-size:12px; font-weight:bold; } .txt1{ font-size:12px; } .pglink{ font-size:12px; text-decoration:underline; color:#0000ff; cursor:hand; } .pgmenu_sel{ border-top-style: solid; border-left-style: solid; border-right-style: solid; border-bottom-style: none; border-top-color: #4466CC; border-left-color: #4466CC; border-right-color: #4466CC; border-top-width: 1px; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 0px; font-weight: bold; font-size: 14px; cursor: default; color:#ee5533; } .pgmenu_unsel{ border-top-style: solid; border-left-style: solid; border-right-style: solid; border-bottom-style: solid; border-top-color: #BBCCDD; border-left-color: #BBCCDD; border-right-color: #BBCCDD; border-bottom-color: #4466CC; border-top-width: 1px; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; background-color: #E6E9EC; font-weight: bold; font-size: 14px; cursor: hand; } .pgmenu_separe{ border-top-style: none; border-left-style: none; border-right-style: none; border-bottom-style: solid; border-bottom-color: #4466CC; border-top-width: 0px; border-left-width: 0px; border-right-width: 0px; border-bottom-width: 1px; } </style> </head> <body onload="pgMain.Initialize()" onbeforeunload="pgMain.Clean()" style="margin:0px;"> <div align="center" style="width:100%;"> <!--创建控件实例--> <object id="pgAtx" classid="clsid:FFC9369F-A8D9-4598-8E22-ED07C7628BFC" width="100%" height="30px"> <a href="http://www.peergine.com/download/peergine_client_v1.0.0.exe">点击这里下载Peergine控件</a> </object><br> <!--菜单条--> <div valign="top" style="width:900px;height:38px;"> <table id="id_menu" width="100%" height="30px" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="pgmenu_separe" width="10"> </td> <td class="pgmenu_sel" align="center" onclick="pgMenu.SelMenu(1, 'id_tab_chat')">聊天室</td> <td class="pgmenu_separe" width="10"> </td> <td class="pgmenu_unsel" align="center" onclick="pgMenu.SelMenu(3, 'id_tab_debug')">调试信息</td> <td class="pgmenu_separe" width="10"> </td> </tr> </table> </div> <!--客户区--> <div style="position:relative;left:0px;top:0px;width:900px;height:500px;"> <!--聊天室窗口--> <div id="id_tab_chat" style="left:0px;top:0px;width:100%;height:100%;border:1px solid #666666;"> <table width="100%" height="100%" cellpadding="0" cellspacing="0" style=""> <tr> <td valign="top" width="600px"> <table width="100%" height="100%" cellpadding="0" cellspacing="0"> <tr> <td valign="top" style="padding:5px;"> <iframe id="id_output" width="100%" height="100%" frameborder="0" scrolling="auto" style="overflow:visible;word-break:keep-all;"> </iframe> </td> </tr> <tr height="70px"> <td align="left" width="100%" style="border-top:1px solid #666666;"> <table width="100%" height="100%" cellpadding="0" cellspacing="0"> <tr> <td align="center" width="5px"> </td> <td style="padding:5px;"> <textarea id="id_input" rows="3" cols="68" onkeyup="pgMain.Enter()"></textarea> </td> <td width="100px" align="center"> <input id="id_message" type="button" value="发送" style="width:60px;height:40px;" onclick="pgMain.SendMsg()"> </td> </tr> </table> </td> </tr> </table> </td> <td valign="top" width="300px" style="border-left:1px solid #666666;"> <table width="100%" height="100%" cellpadding="0" cellspacing="0"> <tr height="50px"> <td style="padding:10px;border-bottom:1px solid #666666;"> 用户名:<input id="id_user" type="text" size="16"> <input type="button" value="登录" onclick="pgMain.Login()"> <input type="button" value="注销" onclick="pgMain.Logout()"> </td> </tr> <tr height="400px"> <td valign="top" style="border-bottom:1px solid #666666;"> <div style="width:100%;height:25px;padding:5px;background-color:#dddddd;">在线用户列表:</div> <div style="width:100%;height:375px;overflow-y:auto;"> <table id="id_user_list" width="100%" cellpadding="0" cellspacing="0" style="padding:8px;"> </table> </div> </td> </tr> <tr height="50px"> <td style="padding:10px;"> <input id="id_audio_ctrl" type="checkbox" onclick="pgMain.AudioCtrl()"> 打开音频</input> </td> </tr> </table> </td> </tr> </table> </div> <!--调试信息窗口--> <div id="id_tab_debug" style="position:absolute;left:0px;top:0px;width:100%;height:100%;border:1px solid #666666;visibility:hidden;"> <table width="100%" height="100%" cellpadding="0" cellspacing="0"> <tr height="25px"> <td align="right" style="border-bottom:1px solid #666666;background-color:#eeeeee;"> <input id="id_debug_switch" type='checkbox' checked="1">允许输出</input> </td> </tr> <tr> <td valign="top"> <iframe id="id_debug_out" width="100%" height="100%" frameborder="0" scrolling="auto" style="overflow:visible;word-break:keep-all;"> </iframe> </td> </tr> </table> </div> </div> </div> <!--演示程序脚本--> <script language="javascript"> var s_sUser = ""; var s_uMethCmnButt = 32; // 类方法ID的起始值 var s_sServer = "PGServer"; // 登录服务器节点对象的名称 var s_sOnline = "PGOnline"; // 在线用户通信组对象名称 var s_sMessage = "PGMessage"; // 聊天消息传输对象的名称 var s_sAudio = "PGAudio"; // 聊天音频传输对象的名称 var s_uLogined = 0; /// // 菜单条控制 var pgMenu = { uCurMenu:1, sCurID:"id_tab_chat", SelMenu:function(uMenu, sID) { id_menu.rows(0).cells(pgMenu.uCurMenu).className = "pgmenu_unsel"; id_menu.rows(0).cells(uMenu).className = "pgmenu_sel"; pgMenu.uCurMenu = uMenu; var oTab1 = document.getElementById(pgMenu.sCurID); if (oTab1) { oTab1.style.visibility = "hidden"; } var oTab2 = document.getElementById(sID); if (oTab2) { oTab2.style.visibility = "inherit"; } pgMenu.sCurID = sID; } } /// // 聊天室功能实现 var pgMain = { Initialize:function() { // 初始化控件 pgAtx.Control = "Type=1"; // 启用节点功能。 pgAtx.Node = "Type=0"; // 作为普通节点 pgAtx.Class = "PG_CLASS_Data:2;PG_CLASS_Audio:2;"; // 使能消息传输类和音频传输类 pgAtx.Local = "Addr=0:0:0:127.0.0.1:0:0"; // 设置缺省的本地节点地址 pgAtx.Server = "Name=" + s_sServer + ";Addr=0:0:0:127.0.0.1:10002:0"; // 设置服务器节点的名称和地址。 pgAtx.Relay = "(Relay0){(Type){0}(Load){0}(Addr){0:0:0:127.0.0.1:7890:0}}"; pgAtx.OnExtRequest = pgOnExtRequest; // 设置接收请求的回调函数 pgAtx.OnReply = pgOnReply; // 设置接收应答的回调函数。 if (!pgAtx.Start(0)) { // 初始化节点功能。Start成功后登录服务器对象s_sServer就已经创建。 debugOutString("Initialize failed"); return false; } return true; }, Clean:function() { // 退出清理 pgMain.Logout(); }, Login:function() { // 登录服务器。 if (id_user.value == "") { alert("用户名不能为空"); return; } // 发送登录请求。 s_sUser = id_user.value + '@' + s_sServer; var sData = "(User){" + pgAtx.omlEncode(s_sUser) + "}(Pass){}(Param){}"; var uErr = pgAtx.ObjectRequest(s_sServer, (s_uMethCmnButt + 0), sData, "pgMain.Login"); if (uErr > 0) { return false; } pgMain.OutString(pgMain.UserTxt(s_sUser) + ": 正在登录……"); return true; }, Logout:function() { // 注销登录。 while (id_user_list.rows.length > 0) { id_user_list.deleteRow(0); } id_audio_ctrl.checked = false; // 删除所有通信对象 pgAtx.ObjectDelete(s_sAudio); pgAtx.ObjectDelete(s_sMessage); pgAtx.ObjectDelete(s_sOnline); // 发送注销请求。 pgAtx.ObjectRequest(s_sServer, (s_uMethCmnButt + 1), "", "pgMain.Logout"); pgMain.OutString(pgMain.UserTxt(s_sUser) + ": 已经注销"); s_uLogined = 0; s_sUser = ""; }, LoginOK:function() { // 登录返回成功。 // 创建在线用户通信组对象。 // 关联服务器节点s_sServer,引用登录服务器上的同名通信对象的成员。 // 启用:PG_METH_COMMON_Sync=0x10000选项,上报对象同步通知 // 启用:PG_ADD_GROUP_Update=0x1选项,上报成员的加入/离开通知 if (!pgAtx.ObjectAdd(s_sOnline, "PG_CLASS_Group", s_sServer, (0x10000 | 0x1))) { debugOutString("Add 'Online' obj failed"); return; } // 创建消息传输对象。 // 关联在线通信组对象s_sOnline。 // 启用:PG_METH_COMMON_Sync=0x10000选项,上报对象同步通知 if (!pgAtx.ObjectAdd(s_sMessage, "PG_CLASS_Data", s_sOnline, 0x10000)) { debugOutString("Add 'Message' obj failed"); return; } pgMain.OutString(pgMain.UserTxt(s_sUser) + ": 登录成功"); document.title = "简单聊天室演示: " + pgMain.UserTxt(s_sUser); s_uLogined = 1; }, UserTxt:function(sUser) { var iInd = sUser.indexOf('@'); if (iInd > 0) { return sUser.substr(0, iInd); } return sUser; }, Enter:function() { // 用回车键发送消息 if (event.keyCode == 13) { pgMain.SendMsg(); } }, SendMsg:function() { if (!s_uLogined) { alert("还没有登录"); return; } if (id_input.value == "") { return; } // 调用PG_METH_DATA_Message方法组播消息到其他节点。 var sData = "(Txt){" + pgAtx.omlEncode(id_input.value) + "}"; pgAtx.ObjectRequest(s_sMessage, (s_uMethCmnButt + 0), sData, "pgMain.SendMsg"); // 显示本地消息到输出窗口 pgMain.OutHTML("<strong style={color:#0033FF;font-size:12px;}>" + pgMain.UserTxt(s_sUser) + "</strong>:<pre style={font-size:12px;word-wrap:break-word;word-break:break-all;white-space:normal;}>" + id_input.value + "</pre>"); id_input.value = ""; }, ShowMsg:function(sData, sPeer) { // 显示从其他节点来的消息到输出窗口 var sTxt = pgAtx.omlGetContent(sData, "Txt"); pgMain.OutHTML("<strong style={color:#FF3300;font-size:12px;}>" + pgMain.UserTxt(sPeer) + "</strong>:<pre style={font-size:12px;word-wrap:break-word;word-break:break-all;white-space:normal;}>" + pgAtx.omlDecode(sTxt) + "</pre>"); }, OutHTML:function(sHtml) { id_output.document.body.insertAdjacentHTML("beforeEnd", sHtml); id_output.document.body.doScroll("pageDown"); }, OutString:function(sOut) { var sHtml = "<pre style={font-size:12px;word-wrap:break-word;word-break:break-all;white-space:normal;}>" + sOut + "</pre>"; pgMain.OutHTML(sHtml); }, AudioCtrl:function() { // 打开/关闭音频通信。 if (!s_uLogined) { id_audio_ctrl.checked = false; alert("还没有登录"); return; } if (id_audio_ctrl.checked) { // 创建音频传输对象 // 关联在线通信组对象s_sOnline // 启用:PG_METH_COMMON_Sync=0x10000选项,上报对象同步通知 // 启用:PG_ADD_AUDIO_Conference=0x1选项,会议模式 if (!pgAtx.ObjectAdd(s_sAudio, "PG_CLASS_Audio", s_sOnline, (0x10000 | 0x1))) { debugOutString("Add 'Audio' obj failed"); return; } // 调用PG_METH_AUDIO_Open方法打开音频传输对象。 var sData = "(Code){0}(Mode){0}"; var iErr = pgAtx.ObjectRequest(s_sAudio, ((s_uMethCmnButt + 0)), sData, "pgMain.OpenAudio"); if (iErr != 0) { debugOutString("Open 'Audio' obj failed:" + iErr); return; } pgMain.OutString("已经打开音频"); } else { // 删除音频传输对象 pgAtx.ObjectDelete(s_sAudio); pgMain.OutString("已经关闭音频"); } }, UpdateUser:function(sData) { // 用户上线/下线通知。 var uAct = pgAtx.omlGetContent(sData, "Action"); var sPeerList = pgAtx.omlGetEle(sData, "PeerList.", 1024, 0); if (sPeerList != "") { var iInd = 0; while (1) { var sItem = pgAtx.omlGetEle(sPeerList, "", 1, iInd); if (sItem == "") { break; } var sUser = pgAtx.omlGetName(sItem, ""); if (sUser != s_sServer) { if (uAct != 0) { // 显示用户上线 pgMain.AddUser(sUser); } else { // 显示用户下线 pgMain.DeleteUser(sUser); } } iInd++; } } }, AddUser:function(sUser) { var sUserTxt = pgMain.UserTxt(sUser); for (var i = 0; i < id_user_list.rows.length; i++) { if (id_user_list.rows[i].innerText == sUserTxt) { return; } } var oRow = id_user_list.insertRow(); var oCell = oRow.insertCell(); oCell.height = "24"; oCell.innerText = sUserTxt; }, DeleteUser:function(sUser) { var sUserTxt = pgMain.UserTxt(sUser); for (var i = 0; i < id_user_list.rows.length; i++) { if (id_user_list.rows[i].innerText == sUserTxt) { id_user_list.deleteRow(i); return; } } } } /// // 调试信息输出 var pgDebug = { OutHTML:function(sHtml) { if (id_debug_switch.checked) { id_debug_out.document.body.insertAdjacentHTML("beforeEnd", sHtml); id_debug_out.document.body.doScroll("pageDown"); } } } function debugOutString(sOut) { pgDebug.OutHTML("<pre style={font-size:12px;word-wrap:break-word;word-break:break-all;white-space:normal;}>" + sOut + "</pre>"); } // 接收请求回调函数。 function pgOnExtRequest(sObj, uMeth, sData, uHandle, sPeer) { debugOutString(sObj + ':' + uMeth + ':' + sData + ':' + sPeer); if (sObj == s_sMessage) { if (uMeth == (s_uMethCmnButt + 0)) { pgMain.ShowMsg(sData, sPeer); } } if (sObj == s_sOnline) { if (uMeth == (s_uMethCmnButt + 1)) { pgMain.UpdateUser(sData); } return 0; } return 0; } // 接收应答回调函数。 function pgOnReply(sObj, uErr, sData, sParam) { debugOutString(sObj + ':' + uErr + ':' + sData + ':' + sParam); if (sObj == s_sServer) { if (sParam == "pgMain.Login") { if (uErr != 0) { pgMain.OutString(pgMain.UserTxt(s_sUser) + ": 登录失败"); s_sUser = ""; return 1; } pgMain.LoginOK(sData); } } return 1; } </script> </body> </html> |
修改内容 | 版本 |
1. 增加“控件的节点功能函数”章节的PostMessage()函数说明
2. 增加“视频采集扩展选项”章节 |
1.5.0 |
1. 在“常量:视频捕捉的尺寸模式”章节中,增加了QCIF、CIF、D1的视频尺寸支持。 | 1.5.1 |
1. PG_METH_VIDEO_Open,方法的Code参数的值增加H264编码常量。
2. 增加“异常离线(掉线)的判断”章节 |
1.5.2 |
1. 在“控件的属性配置项”章节的“Control”配置项中,增加“Sandbox”参数
2. 在“控件的属性配置项”章节的“Node”配置项中,增加“P2PTryTime”和“SocketMDU”参数 3. 在“控件的属性配置项”章节的“Local”配置项中,增加“FwdSpeed”参数 4. 在“PG_CLASS_Peer类”章节中,增加“4)扩展选项”子章节。 5. 在“PG_CLASS_Audio类”章节中,增加“4)扩展选项”子章节。 6. 在“PG_CLASS_Video类”章节中,增加“5)扩展选项”子章节。 7. 在“PG_CLASS_Video类”章节中,增加“6)Android视频采集扩展选项说明”子章节。 8. 在“常量:媒体流的控制动作”章节中,增加“PG_LIVE_CTRL_JpegPull”操作。 9. 在“多种OS平台和软件形态”章节中,修改路标表格。 10. 在“PG_CLASS_Audio类”的“选项”章节中,增加“PG_ADD_AUDIO_OnlyInput”和“PG_ADD_AUDIO_OnlyOutput”选项。 11. 在“PG_CLASS_Video类” 的“选项”章节中,增加“PG_ADD_VIDEO_OnlyInput”和“PG_ADD_VIDEO_OnlyOutput”选项。 |
1.6.0 |
1. 在“PG_CLASS_Peer类”的“方法”章节中,增加“PG_METH_PEER_CheckInfo”、“PG_METH_PEER_LanScan”方法。
2. 在“PG_CLASS_Peer类”的“扩展选项”章节中,增加“PG_OPTION_PEER_SocketLAN”、“PG_OPTION_PEER_LoginTimeout”、“PG_OPTION_PEER_CallTimeout”和“PG_OPTION_PEER_SocketSelect”选项。 3. 在在“PG_CLASS_Audio类”的“扩展选项”章节中增加“PG_OPTION_AUDIO_Detect”选项。 |
1.7.5 |
1. 在“PG_CLASS_Peer类”的“方法”章节中,增加“PG_METH_PEER_AgentLogin”、“PG_METH_PEER_AgentLogout”和“PG_METH_PEER_AgentMessage”方法。
2. 在“PG_CLASS_File类”的“选项”章节中,增加“PG_ADD_FILE_TcpSock”、“PG_ADD_FILE_Flush” 和“PG_ADD_FILE_PeerStop”选项。 3. 在“PG_CLASS_Video类”的“常量:视频捕捉的尺寸模式”章节中增加“PG_VIDEO_MODE_854x480”、“PG_VIDEO_MODE_1280x720”和“PG_VIDEO_MODE_1920x1080”参数。 |
1.8.0 |
1. 在“PG_CLASS_Live类”的“选项”章节中,增加“PG_ADD_LIVE_NoOutput”选项。
2. 在“PG_CLASS_Live类”的“扩展选项”章节中,增加“PG_OPTION_LIVE_RelayNum”和“PG_OPTION_LIVE_NearSize”选项。 |
1.8.5 |
1. 在“PG_CLASS_Peer类”的“扩展选项”章节中,增加“PG_OPTION_PEER_RecvBacklogSize”和“PG_OPTION_PEER_SendBacklogSize”选项。
2. 在“PG_CLASS_Video类”的“选项”章节中,增加“PG_ADD_VIDEO_FrameStat”选项。 3. 在“PG_CLASS_Video类”的“方法”章节中,增加“PG_METH_VIDEO_Transfer”和“PG_METH_VIDEO_FrameStat”方法 4. 在“PG_CLASS_Video类”的“扩展选项”章节中,增加“PG_OPTION_VIDEO_InputExternal”、“PG_OPTION_VIDEO_CameraEnable”和“PG_OPTION_VIDEO_FillMode”选项。 5. 在“PG_CLASS_Live类”的“选项”章节中,增加“PG_ADD_LIVE_LoadFirst”选项。 6. 在“PG_CLASS_Live类”的“方法”章节中,增加“PG_METH_LIVE_Camera”和“PG_METH_LIVE_RelayPeer”方法。 |
1.8.6 |
1. 在“PG_CLASS_Peer类”的“方法”章节中,增加“PG_METH_PEER_ReloginReply”、“PG_METH_PEER_KickOut”、“PG_METH_PEER_AccessCtrl”和“PG_METH_PEER_PushOption”方法。
2. 在“PG_CLASS_Peer类”的“选项”章节中,增加“PG_OPTION_PEER_RelayList”、“PG_OPTION_PEER_ForwardSpeed”、“PG_OPTION_PEER_ForwardGate”和“PG_OPTION_PEER_ForwardTryTime”和“PG_OPTION_PEER_ForwardUse”选项。 3. 在“PG_CLASS_Peer类”的增加“PG_METH_PEER_PushOption方法的选项”章节。 4. 在“PG_CLASS_Video类”的“选项”章节中,增加“PG_ADD_VIDEO_DrawThread”选项。 |
1.12.0 |
1. 在“控件的属性配置项”章节的“Control”配置项中,增加“LogName”、“LogLevel0”、“LogLevel1”、“LogLevel2”、“LogLevel3”、“LogFileNum”和“LogFileSize”参数。
2. 在“控件的属性配置项”章节的“Node”配置项中,增加“Option”参数。 3. 在“PG_CLASS_Peer类”的“扩展选项”章节中,增加“PG_OPTION_PEER_SocketInitWnd”和“PG_OPTION_PEER_SocketLoopSpeed”选项。 4. 在“PG_CLASS_Group类”的“选项”章节中,增加“PG_ADD_GROUP_HearOnly”选项。 5. 在“PG_CLASS_Audio类”的“选项”章节中,增加“PG_ADD_AUDIO_SendReliable”选项。 6. 在“PG_CLASS_Audio类”的“扩展选项”章节中,增加“PG_OPTION_AUDIO_InputExternal”、“PG_OPTION_AUDIO_OutputExternal”、“PG_OPTION_AUDIO_EnableAEC”、“PG_OPTION_AUDIO_SpeakerNo”和“PG_OPTION_AUDIO_SendReliable”选项。 7. 在“PG_CLASS_Video类”的“选项”章节中,增加“PG_ADD_VIDEO_DrawThread”、“PG_ADD_VIDEO_OutputExternal”、“PG_ADD_VIDEO_OutputExtCmp”和“PG_ADD_VIDEO_FilterDecode”选项。 8. 在“PG_CLASS_Video类”的“扩展选项”章节中,增加“PG_OPTION_VIDEO_OutputExternal”、“PG_OPTION_VIDEO_RedefModeSize”、“PG_OPTION_VIDEO_OutputExtCmp”、“PG_OPTION_VIDEO_FlashLight”和“PG_OPTION_VIDEO_AttachCameraNo”选项。 9. 在“PG_CLASS_Live类”的“选项”章节中,增加“PG_ADD_LIVE_DrawThread”、“PG_ADD_LIVE_FrameStat”和“PG_ADD_LIVE_FilterDecode”选项。 10. 在“PG_CLASS_Live类”的“扩展选项”章节中,增加“PG_OPTION_LIVE_AttachCameraNo”选项。 |
1.21.0 |
1. 在“控件的节点功能函数”的章节中,增加“ObjectEnum”和“Stop”函数说明。 | 1.21.1 |
1. 修改PG_METH_AUDIO_CtrlVolume方法的说明 | 1.21.2 |
1.在“PG_CLASS_Audio类”的“选项”章节中,增加“PG_ADD_AUDIO_NoSpeechSelf”和“PG_ADD_AUDIO_NoSpeechPeer”选项 | 1.25.2 |
1. 在“PG_CLASS_Audio类”的“扩展选项”章节中,增加“PG_OPTION_AUDIO_AttachMicNo”和“PG_OPTION_AUDIO_AttachSpeakerNo” | 1.27.0 |
1.在“PG_CLASS_Audio类”的“选项”章节中,增加“PG_ADD_AUDIO_MuteInput”和“PG_ADD_AUDIO_MuteOutput”
2.在“PG_CLASS_Audio类”的“扩展选项”章节中,增加“PG_OPTION_AUDIO_MuteInput”和“PG_OPTION_AUDIO_MuteOutput” 3.在“PG_CLASS_Audio类”的“方法”章节中,“PG_METH_AUDIO_Record”方法增加“HasVideo”参数和“mov”、“mp4”媒体文件格式。 4.在“PG_CLASS_Video类”的“方法”章节中,“PG_METH_VIDEO_Record”方法增加“HasAudio”参数和“mov”、“mp4”媒体文件格式。 5.在“PG_CLASS_Video类”的“方法”章节中,“PG_METH_LIVE_Record”方法增加“HasAudio”和“HasVideo”参数,以及“mov”、“mp4”媒体文件格式。 |
1.28.0 |