更新记录
2.0.0(2021-08-12) 下载此版本
- 新增服务注册功能
- 保留1.x.x版本的接口
1.0.1(2021-07-25) 下载此版本
- 修改startDiscovery()方法输入参数serviceType属性。不给serviceType属性,或是serviceType属性给空字符串都视为没有赋值。
- 修改说明文档
1.0.0(2021-07-19) 下载此版本
初次提交
查看更多平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:5.0 - 11.0 | armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 | × |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
安卓mDNS服务发现与注册原生插件
介绍
基于mDNS的设备发现与注册原生插件,实现在同一广播网段的设备发现。支持作为服务提供方广播服务及作为客户端发现设备所提供的服务。
限制
- 只支持安卓。
使用场景
- 实现手机与智能设备的直接连接,中间不需要通过局网内第三方服务器或广域网的云服务中转。设备不需要固定IP地址,手机通过一固定的服务名称动态发现设备的IP地址并实现连接。
- 零配置实现手机动态发现智能设备。不需要事先配置设备的信息,手机可动态发现同一服务类型的所有设备并选择需要的设备建立连接。
使用方法
本插件支持服务注册与服务发现,两部分是独立,可以单独使用,也可作为服务提供方与客户端同时使用。
服务发现
- 加载插件
// 加载mDNS设备发现插件
// 插件名称为'zodiac-nsd'
const nsd = uni.requireNativePlugin('zodiac-nsd');
// 加载事件监听插件
const globalEvent = uni.requireNativePlugin('globalEvent');
- 初始化
// 初始化插件,可在页面onLoad()中调用
nsd.initDiscovery();
- 注册事件监听回调
// 可在页面onLoad()中调用
// 'discoveryStatusChange'为默认的事件名称
globalEvent.addEventListener('discoveryStatusChange', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容,格式请参考“事件格式”章节
});
- 启动设备发现任务
// id为本次调用发现设备方法返回的的发现任务标识,后续可用来作为停止发现设备
// 任务的入参
// serviceType为服务类型,详见“服务类型”章节
// serviceName为服务名称,详见“服务名称”章节
const id = nsd.startDiscovery({
serviceType: '_http._tcp',
serviceName: ['service1', 'service2']
});
- 停止设备发现任务
// 停止所有发起的设备发现请求
nsd.stopAllDiscovery();
// 或是停止指定的设备发现请求
// id为调用nsd.startDiscovery()的返回值
nsd.stopDiscovery(id);
- 释放资源
// 当插件不再使用时调用
// 可在页面的onUnload()里调用
nsd.cleanUpDiscovery();
服务注册
- 加载插件
// 加载mDNS设备发现插件
// 插件名称为'zodiac-nsd'
const nsd = uni.requireNativePlugin('zodiac-nsd');
// 加载事件监听插件
const globalEvent = uni.requireNativePlugin('globalEvent');
- 初始化
// 初始化插件,可在页面onLoad()中调用
nsd.initRegistration();
- 注册事件监听回调
// 可在页面onLoad()中调用
// 'registrationStatusChange'为默认的事件名称
globalEvent.addEventListener('registrationStatusChange', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容,格式请参考“事件格式”章节
});
- 注册设备提供的服务
// id为本次调用服务注册任务标识,后续可用来作为停止服务注册
// serviceType为服务类型,详见“服务类型”章节
// serviceName为服务名称,详见“服务名称”章节
// ipAddress为服务运行设备的IP地址
// port为服务的监听端口
const id = nsd.registerService({
serviceType: '_http._tcp',
serviceName: 'MyHttpServer',
ipAddress: '192.168.0.100',
port: 8050
});
- 停止服务注册
// 停止所有发起的服务注册请求
nsd.unregisterAllService();
// 或是停止指定的服务注册请求
// id为调用nsd.registerService()的返回值
nsd.unregisterService(id);
- 释放资源
// 当插件不再使用时调用
// 可在页面的onUnload()里调用
nsd.cleanUpRegistration();
服务发现方法
initDiscovery
用途 初始化插件。可在页面onLoad()中调用。
限制 需在调用插件其他服务发现方法之前调用。
输入值 无
返回值 数字类型,1表示初始化成功。0示初始化失败,此时不可再调用插件其他服务发现方法。
startDiscovery
用途 启动设备发现任务。
限制 最多能同时启动五个设备发现任务。
输入值 Object类型,格式如下:
{
serviceType: '_http._tcp',
serviceName: ['service1', 'service2']
}
属性 | 必需 | 类型 | 说明 |
---|---|---|---|
serviceType | 否 | String | 指定欲发现设备的服务类型,可不指定(不给serviceType属性,或是serviceType属性给空字符串),不指定时默认服务类型为'_http._tcp'。服务类型格式请参考‘服务类型’章节说明。 |
serviceName | 否 | Array | 指定欲发现设备的服务名称,如果没有此属性或是给空数组,则表示要发现任何提供该服务类型的设备。如果指定了服务名称,只会返回符合指定服务名称的服务。服务名称的用法请参考‘服务名称’章节说明。 |
如果serviceType及serviceName两个属性都不赋值需要传入空Object {}。如下示例:
// 发现所有提供服务类型为'_http._tcp'的设备
nsd.startDiscovery({});
返回值 数字类型,0表示调用失败,发现任务未启动。大于0表示调用成功,发现任务已启动,返回值为发现任务标识。
stopDiscovery
用途 停止指定的设备发现任务。
限制 需先调用startDiscovery成功后,得到有效的发现任务标识才能调用stopDiscovery。
输入值 数字类型,发现任务标识。
返回值 数字类型,0表示调用失败,可能是输入值发现任务标识对应的发现任务已经停止,或是输入无效的发现任务标识,或是插件功能异常。大于0表示调用成功,此时返回值等于输入值。
返回值大于0只表示调用成功,并不表示任务已经停止,任务如果成功停止会收到'status'为'stopped'(发现任务终止)的事件。详见‘事件格式’章节说明。
stopAllDiscovery
用途 停止所有的设备发现任务。
限制 无
输入值 无
返回值 无
调用方法返回后并不表示发现任务已经停止,任务如果成功停止会收到'status'为'stopped'(发现任务终止)的事件。详见‘事件格式’章节说明。
isDiscovering
用途 检查设备发现任务是否在进行中。
限制 无
输入值 数字类型,发现任务标识。
返回值 数字类型,0表示发现任务标识对应的发现任务没有在进行,可能是发现任务标识无效或是该任务已经停止。1表示发现任务标识对应的发现任务正在进行中。
getNumberOfDiscovery
用途 获取现在正在进行中的设备发现任务数量。
限制 无
输入值 无
返回值 数字类型,大于或等于0。0表示当前无设备发现任务正在进行中,大于0为正在进行中的设备发现任务数量。
getDiscoveryTimeout
用途 获取设备发现任务超时时间,超时时间以秒为单位。调用startDiscovery时可在serviceName属性的数组添加指定的服务名称,当指定了服务名称时,则会有超时情况,未指定服务名称时不会有超时发生。发现任务启动后,在超时时间内发现的设备数量小于指定服务名称的数量则会产生status='failure',errorCode=3的超时事件。默认的超时时间为10秒。
限制 无
输入值 无
返回值 数字类型,设定的超时时间。小于或等于0表示没有设定超时时间。大于0表示以秒为单位的超时时间。
setDiscoveryTimeout
用途 设定设备发现任务超时时间,超时时间以秒为单位。超时时间的作用详见getDiscoveryTimeout方法说明。
限制
- 一般在调用initDiscovery()方法后及调用startDiscovery()方法前调用setDiscoveryTimeout()方法。
- 如果在调用setDiscoveryTimeout()方法之前已经调用了startDiscovery()启动了发现任务,这些发现任务的超时时间不会改变。只有在调用setDiscoveryTimeout()方法之后所启动的发现任务的超时时间才会改变。
输入值 数字类型,以秒为单位的备发现任务超时时间。小于或等于0表示不设定超时时间。大于0表示以秒为单位的超时时间。
返回值 无
getDiscoveryEventName
用途 获取插件发布服务发现事件时的事件名称。默认值为'discoveryStatusChange'。
限制 无
输入值 无
返回值 字符串类型的事件名称。
setDiscoveryEventName
用途 设定插件发布服务发现事件时的事件名称。默认值为'discoveryStatusChange'。调用此方法后插件发布事件的事件名称将会更改,一般在调用globalEvent.addEventListener()方法之前调用setDiscoveryEventName()。
一般情况不需要变更事件名称,除非默认的事件名称与其他插件所用的事件名称冲突。
限制 setEventName()方法一般在调用init()方法之后及调用globalEvent.addEventListener()方法之前调用,如下例:
// 可在页面onLoad()中调用
// 初始化插件
nsd.initDiscovery();
// 变更事件名称
nsd.setDiscoveryEventName('myEventName');
// 注册事件监听回调,监听事件名称为'myEventName'的事件
globalEvent.addEventListener('myEventName', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容,格式请参考“事件格式”章节
});
输入值 字符串类型的事件名称。
返回值 无
cleanUpDiscovery
用途 释放插件服务发现功能资源。可在页面的onUnload()里调用。
限制 当不再使用插件服务发现功能时必需调用。
输入值 无
返回值 无
服务注册方法
initRegistration
用途 初始化插件。可在页面onLoad()中调用。
限制 需在调用插件其他服务注册方法之前调用。
输入值 无
返回值 数字类型,1表示初始化成功。0示初始化失败,此时不可再调用插件其他服务注册方法。
registerService
用途 注册提供的服务。服务注册后其他设备才可发现。
限制 最多能同时注册五个服务。 输入值 Object类型,格式如下:
{
serviceType: '_http._tcp',
serviceName: 'service1',
ipAddress: '192.168.0.100',
port: 8050,
attributes: {
key1: 'value1',
key2: 'value2'
}
}
属性 | 必需 | 类型 | 说明 |
---|---|---|---|
serviceType | 是 | String | 指定欲发现设备的服务类型,服务类型格式请参考‘服务类型’章节说明。 |
serviceName | 是 | String | 指定欲发现设备的服务名称,服务名称的用法请参考‘服务名称’章节说明。 |
ipAddress | 否 | String | 服务运行设备的IP地址。如果不给值将自动获取本机的WIFI IP地址。 |
port | 是 | Number | 服务监听端口。 |
attributes | 否 | Object | 自定义的属性,提供更多关于服务的描述,帮助客户端识别所需的服务。属性值都是字符串类型。这些注册的属性会在服务发现的事件回调中获得。 |
返回值 数字类型,0表示调用失败,服务未注册成功。大于0表示调用成功,返回值为服务注册标识。
unregisterService
用途 停止服务注册,通常在服务停止后也会停止服务注册,服务注册停止后其他设备将无法再发现此服务。
限制 需先调用registerService成功后,得到有效的服务注册标识才能调用unregisterService。
输入值 数字类型,务服务注册标识。
返回值 数字类型,0表示调用失败,可能是输入值务服务注册标识对应的服务注册已经停止,或是输入无效的服务注册标识,或是插件功能异常。大于0表示调用成功,此时返回值等于输入值。
返回值大于0只表示调用成功,并不表示任服务注册已经停止,服务注册如果成功停止会收到'status'为'unregistered'(服务注册终止)的事件。详见‘事件格式’章节说明。
unregisterAllService
用途 停止所有的服务注册。
限制 无
输入值 无
返回值 无
调用方法返回后并不表示服务注册已经停止,服务注册如果成功停止会收到'status'为''unregistered(服务注册终止)的事件。详见‘事件格式’章节说明。
isValidRegistration
用途 检查服务注册是否是有效。
限制 无
输入值 数字类型,服务注册标识。
返回值 数字类型,0表示服务注册标识对应的服务注册是无效的,可能是服务注册标识无效或是该服务注册已经停止。1表示服务注册标识对应的服务注册正在进行中。
getNumberOfRegistration
用途 获取现在正在进行中的服务注册数量。
限制 无
输入值 无
返回值 数字类型,大于或等于0。0表示当前无服务注册,大于0为正在注册的服务数量。
getRegistrationTimeout
用途 获取服务注册或注销超时时间,超时时间以秒为单位。调用registerService()或unregisterService()后,如果在超时时间内未完成注册或注销服务则会收到status='failure',errorCode=12的超时事件。收到超时事件后服务注册或注销仍在进行,直到成功或失败为止,超时事件只是告警。默认的超时时间为10秒。服务注册或注销使用同样的超时时间,不能分别设定。
限制 无
输入值 无
返回值 数字类型,设定的超时时间。小于或等于0表示没有设定超时时间。大于0表示以秒为单位的超时时间。
setRegistrationTimeout
用途 设定服务注册或注销超时时间,超时时间以秒为单位。超时时间的作用详见getRegistrationTimeout方法说明。
限制
- 一般在调用initRegistration()方法后及调用registerService()方法前调用setRegistrationTimeout()方法。
- 如果在调用setRegistrationTimeout()方法之前已经调用了registerService()开始了服务注册,这些服务注册的超时时间不会改变。只有在调用setRegistrationTimeout()方法之后所开始的服务注册的超时时间才会改变。
输入值 数字类型,以秒为单位的服务注册超时时间。小于或等于0表示不设定超时时间。大于0表示以秒为单位的超时时间。
返回值 无
getRegistrationEventName
用途 获取插件发布服务注册或注销事件时的事件名称。默认值为'registrationStatusChange'。
限制 无
输入值 无
返回值 字符串类型的事件名称。
setRegistrationEventName
用途 设定插件发布服务注册或注销事件时的事件名称。默认值为'registrationStatusChange'。调用此方法后插件发布事件的事件名称将会更改,一般在调用globalEvent.addEventListener()方法之前调用setRegistrationEventName()。
一般情况不需要变更事件名称,除非默认的事件名称与其他插件所用的事件名称冲突。
限制 setRegistrationEventName()方法一般在调用init()方法之后及调用globalEvent.addEventListener()方法之前调用,如下例:
// 可在页面onLoad()中调用
// 初始化插件
nsd.initRegistration();
// 变更事件名称
nsd.setRegistrationEventName('myEventName');
// 注册事件监听回调,监听事件名称为'myEventName'的事件
globalEvent.addEventListener('myEventName', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容,格式请参考“事件格式”章节
});
输入值 字符串类型的事件名称。
返回值 无
cleanUpRegistration
用途 释放插件服务注册功能资源。可在页面的onUnload()里调用。
限制 当不再使用插件服务注册功能时必需调用。
输入值 无
返回值 无
服务发现及服务注册共用的方法
cleanUp
用途 释放插件服务发现及服务注册功能资源。可在页面的onUnload()里调用。如果同时使用了服务发现及服务注册功能(调用了initDiscovery()及initRegistration()),可调用cleanUp()释放服务发现及服务注册功能资源不需要分别调用cleanUpDiscovery()及cleanUpRegistration()。
限制 当不再使用插件时必需调用。
输入值 无
返回值 无
服务发现事件格式
在注册事件监听回调时,如下例:
globalEvent.addEventListener('discoveryStatusChange', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容
});
第一个参数'discoveryStatusChange'为事件名称,第二个参数为回调函数,回调函数入参e格式为:
{
status: 'discovered',
discoveryId: 1,
serviceType: '_http._tcp',
serviceName: 'service1',
ipAddress: '192.168.0.100',
port: 80,
attributes: {
deviceId: '0001',
model: 'xxx'
},
errorCode: 1
}
属性名 | 类型 | 必须 | 说明 |
---|---|---|---|
status | String | 是 | 发现任务的状态。可为'discovered'(发现设备),'stopped'(发现任务终止),'failure'(发现任务发生错误)。当值为'discovered',有效属性为'discoveryId', 'serviceType', 'serviceName', 'ipAddress', 'port', 'attributes'。当值为'stopped'时,有效属性为'discoveryId'。当值为'failure'时,有效属性为'discoveryId','errorCode',当'errorCode'为4时,有效属性再增加'serviceType'及'serviceName'。 |
discoveryId | Number | 是 | 发现任务的标识。与调用startDiscovery()方法的返回值对应。 |
serviceType | String | 否 | 发现任务的服务类型。请参考‘服务类型’章节说明。 |
serviceName | String | 否 | 发现任务的服务名称。请参考‘服务名称’章节说明。 |
ipAddress | String | 否 | 被发现设备的IP地址。只有在'status'属性值为'discovered'时有效。 |
port | Number | 否 | 被发现设备的服务端口。只有在'status'属性值为'discovered'时有效。 |
attributes | Object | 否 | 被发现设备提供服务的详细信息。只有在'status'属性值为'discovered'时有效。attributes Object内的属性及属性值由设备提供方自由定义,没有固定内容。attributes Object内的属性值都是字符串类型,内容为经过Base64编码的二进制数组。 |
errorCode | Number | 否 | 错误代码。当'status'属性值为'failure'时有效。'errorCode'有效值为1,2,3,4。1为发生无法恢复的错误,此时发现任务自动被终止。2为发生可恢复的错误,此时发现任务仍在进行中。3为在限定时间内未找到所有指定的设备,此时发现任务仍在进行中。4为设备暂时失联,此时发现任务仍在进行中,后续设备可能会再次被发现。 |
服务注册事件格式
在注册事件监听回调时,如下例:
globalEvent.addEventListener('registrationStatusChange', (e) => {
// 在此处理事件的相应逻辑
// 参数e为事件的详细内容
});
第一个参数'registrationStatusChange'为事件名称,第二个参数为回调函数,回调函数入参e格式为:
{
status: 'registered',
registrationId: 1,
serviceType: '_http._tcp',
serviceName: 'service1',
ipAddress: '192.168.0.100',
port: 80,
attributes: {
deviceId: '0001',
model: 'xxx'
},
errorType: 'registration'
errorCode: 11
}
属性名 | 类型 | 必须 | 说明 |
---|---|---|---|
status | String | 是 | 服务注册或注销的状态。可为'registered'(服务已注册),'unregistered'(服务已注销),'failure'(服务注册或注销发生错误)。当值为'registered'或'unregistered',有效属性为'registrationId', 'serviceType', 'serviceName', 'ipAddress', 'port', 'attributes'。当值为'failure'时,有效属性为'registrationId','errorCode'及'errorType'。 |
registrationId | Number | 是 | 服务注册标识。与调用registerService()方法的返回值对应。 |
serviceType | String | 否 | 注册的服务类型。请参考‘服务类型’章节说明。 |
serviceName | String | 否 | 注册的服务名称。请参考‘服务名称’章节说明。 |
ipAddress | String | 否 | 注册服务的IP地址。只有在'status'属性值为'registered'或'unregistered'时有效。 |
port | Number | 否 | 注册服务的端口。只有在'status'属性值为'registered'或'unregistered'时有效。 |
attributes | Object | 否 | 注册服务的详细信息。只有在'status'属性值为'registered'或'unregistered'时有效。attributes Object内的属性及属性值在调用registerService()方法时设定。attributes Object内的属性值都是字符串类型,内容为经过Base64编码的二进制数组。 |
errorType | String | 否 | 错误类型。当'status'属性值为'failure'时有效。当值为'registration'表示错误是注册服务时发生。当值为'unregistration'表示错误是注销服务时发生。 |
errorCode | Number | 否 | 错误代码。当'status'属性值为'failure'时有效。'errorCode'有效值为11,12,13,14。11为重复注册。12为服务注册超时(请参考getRegistrationTimeout()方法的有关超时说明)。13为服务注销超时。14为插件内部发生错误。 |
服务类型
每个发现任务以服务类型作为区分,服务类型可理解为设备提供服务所使用的网络协议,例如www服务使用基于tcp的http网络协议,服务类型为'_http._tcp'
。已注册的服务类型可参考Service Name and Transport Protocol Port Number Registry。服务类型的格式为:
_<Service Name>._<Transport Protocol>
<Service Name>
及<Transport Protocol>
可在上述的已注册的服务类型网页里查找。
服务名称
服务名称为提供服务设备所发布用来识别服务的名称,没有标准格式,内容没有限定,需要知道设备提供方的服务命名规则。
其他注意事项
服务发现
- 只支持同时启动5个发现任务。调用startDiscovery()五次返回五个不同的id,调用第六次及以上都会返回0,除非调用stopDiscovery()或stopAllDiscovery()停止发现任务,否则无法再启动发现任务。
- 发现任务有正常停止及非正常停止,正常停止是调用stopDiscovery(),stopAllDiscovery()或cleanUpDiscovery()引起的,这时事件监听回调会收到任务停止的事件,status值为'stopped'。非正常停止是发现任务遇到不可恢复的错误会自动停止,事件监听回调会收到任务失败的事件,status值为'failure',errorCode为1。请注意status值为'failure'时,只有当errorCode为1时发现任务才会被终止,errorCode非1时发现任务仍在进行。
- 发现任务进行中可能会有多次的'发现设备'及'设备失联'的事件产生,可能网络的不稳定导致或是设备停止服务再启动服务。
服务注册
- 只支持同时启动5个服务注册。调用registerService()五次返回五个不同的id,调用第六次及以上都会返回0,除非调用unregisterService()或unregisterAllService()停止服务注册,否则无法再开始新的服务注册。
- 调用registerService()时需要提供本机的ip地址,如不提供,插件会自动寻找WIFI连接的ip地址,由于WIFI没有连接,还有网络环境的复杂性等因素,自动获取的ip地址可能不准确。如果要获取正确的ip地址,请自行实现ip地址获取逻辑,再传给registerService()。