Skip to content

发现服务

说明:主要对发现服务进行一些基础操作,例如节点注册、中继查询、地址上报、地址解析等。

一个典型的终端流程为: 收集地址->地址上报->等待套接字里面的请求

请求地址

开发调试环境(pre)

HTTP协议 http://sls1-scd.star-lock.cn:8080

节点注册

  • 调用方法
http
POST {{urlPrefix}}/SL-A-1.0/peer/register
Content-Type: application/json
  • 参数说明
名称类型是否必需示例描述
productstringY"XHJ-LOCK-711"产品名称
modelstringY"711-ble-plus"产品的型号和规格字符串
namestringY"幸福小区2楼家门锁"对最终用户显示的名称,不可为空
uniquestringY"TMH-1576dd48c9f8"MAC地址/唯一名称/SN序列化,用于对设备进行唯一定位

name字段不可为空,其他字段均为自定义,长度不超过255字节即可,无任何格式要求,也没有唯一性限制,仅为管理后台中筛选和后续对接其他终端时调试使用。

对于智能设备字段建议定义:

  • product: 产品名称
  • model: 产品的型号和规格字符串
  • name: 对最终用户显示的名称
  • unique: MAC地址/唯一名称/SN序列化均可,用于对设备进行唯一定位

对于APP字段建议定义:

  • product: APP名称
  • model: 平台+型号,例如 iPhone15 Plus
  • name: 设备的名称字符串,例如 王晓明的iPhone,如果取不到,可以是其他任何能区分这个iPhone和其他iPhone的字符串
  • unique: MAC地址/唯一名称/SN序列化均可,用于对设备进行唯一定位
  • 返回说明
名称类型描述
msgstring响应消息
peerobject对等节点信息对象
peer.idstring对等节点ID,使用RSA公钥的sha256->base58形成
peer.publicKeystringRSA公钥的HEX格式,约580长度的字符串
peer.privateKeystringRSA私钥的HEX格式,约2300长度的字符串

终端需要将peer字段保存到持久储存,一般只需要在设备第一次通电(或者APP启动)时注册一次。

  • 返回示例
json
{
  "msg": "success",
  "peer": {
    "id": "8dBGekdM7dJ6fcrDVcQYap95S68w5HNrS86ge3jjdJsJ",
    "publicKey": "约580长度的字符串,hex格式",
    "privateKey": "约2300长度的字符串,hex格式"
  }
}

中继查询

查询可用中继等信息用于后续步骤。

  • 调用方法
http
GET {{urlPrefix}}/SL-A-1.0/relay/query
  • 返回说明
名称类型描述
msgstring响应消息
timeint时间戳
stun_serverstringSTUN服务器地址
client_addrstring客户端地址
relay_listarray|null中继列表,如果没有可用中继则为null
relay_list[].peerIDstring中继节点ID
relay_list[].namestring中继节点名称
relay_list[].listenAddrstring监听地址
relay_list[].peerMaxint最大负载连接数
relay_list[].peerCurrentint当前负载连接数
relay_list[].healthint健康状态
relay_list[].latencyint延迟(毫秒)
  • 返回示例
json
{
  "msg": "success",
  "time": 1730286096,
  "stun_server": "stun.syncthing.net:3478",
  "client_addr": "127.0.0.1",
  "relay_list": [
    {
      "peerID": "BBGny2DUmDmtMN1gi8zXT4P5qkZ6E2Sy7yzvqbNQJRqX",
      "name": "scrd1",
      "listenAddr": "udp://10.1.52.155:8083",
      "peerMax": 100,
      "peerCurrent": 0,
      "health": 0,
      "latency": 200
    }
  ]
}

注意:如果没有可用中继,则relay_list字段为null

地址上报

在进行了上一步的操作后,我们已经准备好了一些信息,现在将这些信息都上报到发现服务中。

请求签名算法

签名参数的计算方法:

cpp
signData = binary.LittleEndian.PutUint32(time.CurrentTimestamp())
sign = hex.EncodeToString(rsa.SignPKCS1v15(RsaPrivateKey, sha256.Sum256(signData)))

这段伪代码的目的是生成一个基于当前时间戳的签名。以下是对每一行代码的解释:

  1. signData = binary.LittleEndian.PutUint32(time.CurrentTimestamp())
  • 这里获取了当前时间的时间戳(time.CurrentTimestamp())。
  • 然后将这个时间戳(通常是一个整数)以小端字节序的形式编码为二进制数据。binary.LittleEndian.PutUint32 将这个32位的时间戳转换成一个固定长度的字节数组。
  • signData 变量最终包含了这个以小端方式编码的二进制时间戳。
  1. sign = hex.EncodeToString(rsa.SignPKCS1v15(RsaPrivateKey, sha256.Sum256(signData)))
  • 首先,对 signData 进行 SHA-256 哈希运算,得到一个哈希值。sha256.Sum256(signData) 会返回一个哈希值的数组。
  • 使用 RSA 的 SignPKCS1v15 函数和给定的 RsaPrivateKey 对这个哈希值进行签名。这是基于 PKCS #1 v1.5 的 RSA 签名算法。
  • 签名结果是一个二进制数据,然后用 hex.EncodeToString 将这个二进制数据编码成一个十六进制的字符串格式。
  • 最终,sign 变量中保存的是这个签名的十六进制字符串。

总结 整个流程的作用是:

  1. 将当前时间戳转换为一个小端编码的二进制数据。
  2. 对这个时间戳生成的二进制数据进行 SHA-256 哈希计算。
  3. 使用 RSA 私钥对哈希值进行签名。
  4. 将签名结果编码为十六进制字符串格式。
  • 调用方法
http
POST {{urlPrefix}}/SL-A-1.0/peer/login
Content-Type: application/json
  • 参数说明
名称类型是否必需示例描述
idstringY"8dBGekdM7dJ6fcrDVcQYap95S68w5HNrS86ge3jjdJsJ"对等节点ID
public_keystringY"约580长度的字符串,hex格式"RSA公钥的HEX格式
listen_addrarrayY见示例监听地址列表,按照syncthing的地址格式,搜集所有可用于建立连接的地址
listen_addr[].typestringY"local"地址类型:local(本地地址)、externally(外网地址)、relay(中继地址)
listen_addr[].addressstringY"tcp://192.168.1.2:1888"地址字符串,格式为协议://地址:端口
relay_serviceobjectN见示例如果本节点实现了中继服务,在这个对象中公布自己
relay_service.namestringN"公益-aliyun-1"中继节点名称,自定义
relay_service.listen_addrstringN"tcp://aliyun-1.com:8000"监听的地址
relay_service.peers_maxintN1000最大负载连接数
relay_service.peers_currentintN0当前负载连接数
timeintY1730286096当前时间戳
signstringY"签名的十六进制字符串"基于时间戳的RSA签名

listen_addr字段说明:

按照syncthing的地址格式,搜集所有可用于建立连接的地址 收集地址部分包括:

  1. 监听端口并收集所有网卡地址(4&6)
  2. [可选]UPNP得到自己的上层路由地址
  3. 在中继查询接口获得自己的外网地址端口(注意:在HTTP接口无法得到此字段,因为不是使用的同一个socket,所以http接口只会反馈IP,外网地址还是需要使用STUN服务获取)
  4. 中继上线得到中继地址 最终形成一个由若干个地址组成的地址列表,将列表和自己的唯一ID进行地址上报。

收集地址示意图:

diagram
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0NjJweCIgaGVpZ2h0PSI1NTJweCIgdmlld0JveD0iLTAuNSAtMC41IDQ2MiA1NTIiIGNvbnRlbnQ9IiZsdDtteGZpbGUgaG9zdD0mcXVvdDtlbWJlZC5kaWFncmFtcy5uZXQmcXVvdDsgYWdlbnQ9JnF1b3Q7TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzEzMS4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMzEuMC4wLjAmcXVvdDsgdmVyc2lvbj0mcXVvdDsyNC44LjYmcXVvdDsmZ3Q7Jmx0O2RpYWdyYW0gaWQ9JnF1b3Q7X0pEalRqTmxGWTh3QkxCY2ttM0cmcXVvdDsgbmFtZT0mcXVvdDvnrKwgMSDpobUmcXVvdDsmZ3Q7MVZyYmJ1TTJFUDBhdmhyV2hibzhTcGF5VzZBdGlxYUxkcDhLcnNYWTJzcW1RZE8yM0svdlVLS3NDNW1zbTdVdExZSWc1SEJFaTRkelpnN3BJR2V4S1Q5d3Nsdi93akphSUh1ZWxjaEprRzFiMXR5RFA5SnlyaTJCNWRlR0ZjOHo1ZFFhbnZOL3FUTE9sZldRWjNUZmN4U01GU0xmOVkxTHR0M1NwZWpaQ09mczFIZDdZVVgvVTNka1JUWEQ4NUlVdXZYUFBCTnJ0UXJiYiswZmFiNWFONTlzZVdFOXNpR05zMXJKZmsweWR1cVluQlE1Qzg2WXFGdWJja0VMQ1Y2RFMvM2MweXVqbHhmamRDdXVlY0N0SHppUzRxRFdwdDVMbkp2RjBneldycnFNaXpWYnNTMHAwdFlhYzNiWVpsVE9PSWRlNi9Nell6c3dXbUQ4U29VNHE0MGtCOEhBdEJhYlFvM3FiNjBXc21jSHZsVHZvZDVNRUw2aXlzdXBUZklOTzQrcGxYNmdiRU1GUDRNRHB3VVIrYkcvZTBRRndlcmkxK0lFRFFXVkdUWmJoeTNGS0Y2Z1lDNGJrWStDV0FOeUx6ajc1eEl3ZGg4Q0NJU2Q5TnVVSzhtWjJVdkJUc3MxNFdLMmh4V0x2NlhQYVowTCtyd2pGU0luY0hzTHVpUGxncFp2d3RLTWVpb1l6NFArcVkxdGE2NXM2MDVjTjM3Zmc2UTFqUWdFOVBqNUwvVjgxZmtzT3pQY2RKT3lPNWljVmUrcXlMVkNQWFN0MFdMWENpWkxjU05RL21na24wOGlOSzlDempFQUY0NEZuR1BJamg0S24xQ0VVUnFnQ0JwZ2NWRU1EVXNPQlpZMERyRTFwYnR1eHRUUzZTMXlJZTduUXR1VUMrMTc1VUpMdytDUnFjL3Fwejc3SnJuUG4xRFY5ZzE4OWdwNHF6akxqOUJjaVdwVnRla0xIMXBnK3E0ZjFQbmdDWVVRd0ZEdFV4VFBxeUFIQ1pCVVExRVYyeGlGSVlyMGpQdE9MWkFSUWI2UVBiMmZHSENIWXNBM0VBRGZpUUNodGtIUGYzejZWU2RGVVlEU2Z3MkVEcEJrdjZ2bC8wdGVTb3JjQWlESEdtUUlBMEN1QVIvM0ZnbENyMGkvQTBuT0UwUElIaURrUGhBaFUrMkJTZ05WSjVGRWpXTXB6bXNMVUZSYUlsbUhESGxBQ3ZvVWhYN0Y1cURpdHo0UmxveVBLOUVmSmxMOW0zT0ZQajJ2OSsxSzcwTUcreFpKRk95bnNpeG44Q3VST01PeVg1bGlBclhVR2RSUzE1Uks3bFpMc1RtWDZFTGt1cTJIQnB6ckZ0WFdKMVhXSDI0OUxRWGxVSGlMZDI3cnJQcUJ2bVU3THY2UjluWCt5SDMxeHRCSVYwa2Q0K2tGanlWMkxJUGFxUVdLak9KTDhJWlNmQ3ZKa3FMQXU1SU8ra1R2em9RRlc1TGlPeWxqMjNZcjVyNnAzTjZlRmVFNDN4MDloSlAvUC9FRTJYblJLOTlpWjNBRGRvNTllZFBlMTN6dUhWbHVmSG5UK0kzQWFsMGlLMWFHTlU5akVEU2ZrdCtxVzBoY2NkYVR4SllGRDB2cEV2cVRpTkxoT2R0NTVEbTdPWUZPc0laY3ZzN29STnQ0RjJCNnJQem9iRGJoYTN1akFkendwcy9tUVNGdFR5dGVkYTJBSjhsZ2pCL0pZTU8zQmdiZzZzVG9WMXJmTWwzRGpIcE9kc01CZ29aS2ZhOXpzcTBmajZyd0N0U0ZWaGlod1AwcG1SWmcyQmtSTU04QW1DOHJhaEFxZ1F3SFJLbUxzUkxJSUtxamRKSlU5ZTVJVmVpMjMxNVhZNTMvQVhEUy93QT0mbHQ7L2RpYWdyYW0mZ3Q7Jmx0Oy9teGZpbGUmZ3Q7Ij48ZGVmcy8+PGc+PGcgZGF0YS1jZWxsLWlkPSIwIj48ZyBkYXRhLWNlbGwtaWQ9IjEiPjxnIGRhdGEtY2VsbC1pZD0iNCI+PGc+PHBhdGggZD0iTSA2MSA2MSBMIDYxIDk0LjYzIiBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ic3Ryb2tlIi8+PHBhdGggZD0iTSA2MSA5OS44OCBMIDU3LjUgOTIuODggTCA2MSA5NC42MyBMIDY0LjUgOTIuODggWiIgZmlsbD0icmdiKDAsIDAsIDApIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjIiPjxnPjxlbGxpcHNlIGN4PSI2MSIgY3k9IjMxIiByeD0iNTAiIHJ5PSIzMCIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLXdpZHRoPSIyIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiA5OHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDMxcHg7IG1hcmdpbi1sZWZ0OiAxMnB4OyI+PGRpdiBkYXRhLWRyYXdpby1jb2xvcnM9ImNvbG9yOiByZ2IoMCwgMCwgMCk7ICIgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IHJnYigwLCAwLCAwKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgb3ZlcmZsb3ctd3JhcDogbm9ybWFsOyI+5byA5aeLPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjYxIiB5PSIzNSIgZmlsbD0icmdiKDAsIDAsIDApIiBmb250LWZhbWlseT0iJnF1b3Q7SGVsdmV0aWNhJnF1b3Q7IiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPuW8gOWnizwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjE0Ij48Zz48cGF0aCBkPSJNIDEyMSAyMzEgTCAxNjEgMjMxIEwgMTYxIDM0MSBMIDE5NC42MyAzNDEiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48cGF0aCBkPSJNIDE5OS44OCAzNDEgTCAxOTIuODggMzQ0LjUgTCAxOTQuNjMgMzQxIEwgMTkyLjg4IDMzNy41IFoiIGZpbGw9InJnYigwLCAwLCAwKSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxOCI+PGc+PHBhdGggZD0iTSAxMjEgMjMxIEwgMTYxIDIzMSBMIDE2MSAxOTEgTCAxOTQuNjMgMTkxIiBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ic3Ryb2tlIi8+PHBhdGggZD0iTSAxOTkuODggMTkxIEwgMTkyLjg4IDE5NC41IEwgMTk0LjYzIDE5MSBMIDE5Mi44OCAxODcuNSBaIiBmaWxsPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMjAiPjxnPjxwYXRoIGQ9Ik0gNjEgMTYxIEwgNjEgMTk0LjYzIiBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ic3Ryb2tlIi8+PHBhdGggZD0iTSA2MSAxOTkuODggTCA1Ny41IDE5Mi44OCBMIDYxIDE5NC42MyBMIDY0LjUgMTkyLjg4IFoiIGZpbGw9InJnYigwLCAwLCAwKSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIzIj48Zz48cmVjdCB4PSIxIiB5PSIxMDEiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjAiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS13aWR0aD0iMiIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTE4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTMxcHg7IG1hcmdpbi1sZWZ0OiAycHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij7mn6Xor6Lkv6Hmga88L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iNjEiIHk9IjEzNSIgZmlsbD0icmdiKDAsIDAsIDApIiBmb250LWZhbWlseT0iJnF1b3Q7SGVsdmV0aWNhJnF1b3Q7IiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPuafpeivouS/oeaBrzwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjExIj48Zz48cGF0aCBkPSJNIDMxMSA0MSBMIDIxNiA0MSBMIDIxNiAxMTYgTCAxMjcuMzcgMTE2IiBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ic3Ryb2tlIi8+PHBhdGggZD0iTSAxMjIuMTIgMTE2IEwgMTI5LjEyIDExMi41IEwgMTI3LjM3IDExNiBMIDEyOS4xMiAxMTkuNSBaIiBmaWxsPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iNyI+PGc+PHBhdGggZD0iTSAzMTEgNjEgTCAzMTEgMjEgQyAzMTEgMTUuNDggMzQ0LjU4IDExIDM4NiAxMSBDIDQyNy40MiAxMSA0NjEgMTUuNDggNDYxIDIxIEwgNDYxIDYxIEMgNDYxIDY2LjUyIDQyNy40MiA3MSAzODYgNzEgQyAzNDQuNTggNzEgMzExIDY2LjUyIDMxMSA2MSBaIiBmaWxsPSJyZ2IoMjU1LCAyNTUsIDI1NSkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gMzExIDIxIEMgMzExIDI2LjUyIDM0NC41OCAzMSAzODYgMzEgQyA0MjcuNDIgMzEgNDYxIDI2LjUyIDQ2MSAyMSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiAxNDhweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiA0MXB4OyBtYXJnaW4tbGVmdDogMzEycHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij48ZGl2PjxiciAvPjwvZGl2PuWPkeeOsOacjeWKoeWZqDwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSIzODYiIHk9IjQ1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+JiN4YTvlj5HnjrDmnI3liqHlmag8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSI5Ij48Zz48ZWxsaXBzZSBjeD0iMTgxIiBjeT0iMTMxIiByeD0iMjAiIHJ5PSIyMCIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMzhweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiAxMzFweDsgbWFyZ2luLWxlZnQ6IDE2MnB4OyI+PGRpdiBkYXRhLWRyYXdpby1jb2xvcnM9ImNvbG9yOiByZ2IoMCwgMCwgMCk7ICIgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IHJnYigwLCAwLCAwKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgb3ZlcmZsb3ctd3JhcDogbm9ybWFsOyI+U1RVTjwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSIxODEiIHk9IjEzNSIgZmlsbD0icmdiKDAsIDAsIDApIiBmb250LWZhbWlseT0iJnF1b3Q7SGVsdmV0aWNhJnF1b3Q7IiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPlNUVU48L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxMCI+PGc+PGVsbGlwc2UgY3g9IjE5MSIgY3k9IjEwMSIgcng9IjIwIiByeT0iMjAiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuNSAtMC41KSI+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5IiBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDM4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTAxcHg7IG1hcmdpbi1sZWZ0OiAxNzJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPlJlbGF5PC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjE5MSIgeT0iMTA1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+UmVsYXk8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxMyI+PGc+PHJlY3QgeD0iMjAxIiB5PSIzMTEiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjAiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS13aWR0aD0iMiIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTE4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMzQxcHg7IG1hcmdpbi1sZWZ0OiAyMDJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPuS4ree7p+S4iue6vzxkaXY+5b6X5Yiw5Lit57un5Zyw5Z2APC9kaXY+PGRpdj5yZWxheTwvZGl2PjxkaXY+dWRwOi8veHh4Lnh4eC9teWlkPC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjI2MSIgeT0iMzQ1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5Lit57un5LiK57q/5b6X5Yiw5Lit57un5Zyw5Z2AcmVsYXkuLi48L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxNSI+PGc+PHJlY3QgeD0iMjAxIiB5PSIyNDEiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjAiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS13aWR0aD0iMiIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTE4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMjcxcHg7IG1hcmdpbi1sZWZ0OiAyMDJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPlNUVU7mn6Xor6I8ZGl2PuW+l+WIsOWFrOe9keWcsOWdgGV4dGVybmFsbHk8L2Rpdj48ZGl2PnVkcDovL3gueC54Lng6MTIzNDU8L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMjYxIiB5PSIyNzUiIGZpbGw9InJnYigwLCAwLCAwKSIgZm9udC1mYW1pbHk9IiZxdW90O0hlbHZldGljYSZxdW90OyIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5TVFVO5p+l6K+iLi4uPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTYiPjxnPjxwYXRoIGQ9Ik0gMTIxIDIzMSBMIDE2MSAyMzEgTCAxNjEgMjcxIEwgMTk0LjYzIDI3MSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9InN0cm9rZSIvPjxwYXRoIGQ9Ik0gMTk5Ljg4IDI3MSBMIDE5Mi44OCAyNzQuNSBMIDE5NC42MyAyNzEgTCAxOTIuODggMjY3LjUgWiIgZmlsbD0icmdiKDAsIDAsIDApIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjE3Ij48Zz48cmVjdCB4PSIyMDEiIHk9IjE1MSIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI4MCIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLXdpZHRoPSIyIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiAxMThweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiAxOTFweDsgbWFyZ2luLWxlZnQ6IDIwMnB4OyI+PGRpdiBkYXRhLWRyYXdpby1jb2xvcnM9ImNvbG9yOiByZ2IoMCwgMCwgMCk7ICIgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IHJnYigwLCAwLCAwKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgb3ZlcmZsb3ctd3JhcDogbm9ybWFsOyI+5pys5Zyw6YGN5Y6GPGRpdj7lvpfliLDmnKzlnLDlnLDlnYA8L2Rpdj48ZGl2PmxvY2FsPC9kaXY+PGRpdj51ZHA6Ly94LngueC54OjIyMjIyPGJyIC8+PC9kaXY+PGRpdj51ZHA6Ly9baXB2Nl06MjIyMjI8YnIgLz48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMjYxIiB5PSIxOTUiIGZpbGw9InJnYigwLCAwLCAwKSIgZm9udC1mYW1pbHk9IiZxdW90O0hlbHZldGljYSZxdW90OyIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7mnKzlnLDpgY3ljoblvpfliLDmnKzlnLDlnLDlnYBsb2NhbC4uLjwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjIyIj48Zz48cGF0aCBkPSJNIDYxIDI2MSBMIDYxIDM4NC42MyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9InN0cm9rZSIvPjxwYXRoIGQ9Ik0gNjEgMzg5Ljg4IEwgNTcuNSAzODIuODggTCA2MSAzODQuNjMgTCA2NC41IDM4Mi44OCBaIiBmaWxsPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTkiPjxnPjxyZWN0IHg9IjEiIHk9IjIwMSIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2MCIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLXdpZHRoPSIyIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiAxMThweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiAyMzFweDsgbWFyZ2luLWxlZnQ6IDJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPuWIm+W7ulVEUOWll+aOpeWtlzwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSI2MSIgeT0iMjM1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5Yib5bu6VURQ5aWX5o6l5a2XPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMjMiPjxnPjxwYXRoIGQ9Ik0gMTIxIDQyMSBMIDM4NiA0MjEgTCAzODYgNzcuMzciIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48cGF0aCBkPSJNIDM4NiA3Mi4xMiBMIDM4OS41IDc5LjEyIEwgMzg2IDc3LjM3IEwgMzgyLjUgNzkuMTIgWiIgZmlsbD0icmdiKDAsIDAsIDApIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjI3Ij48Zz48cGF0aCBkPSJNIDYxIDQ1MSBMIDYxIDQ4NC42MyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9InN0cm9rZSIvPjxwYXRoIGQ9Ik0gNjEgNDg5Ljg4IEwgNTcuNSA0ODIuODggTCA2MSA0ODQuNjMgTCA2NC41IDQ4Mi44OCBaIiBmaWxsPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMjEiPjxnPjxyZWN0IHg9IjEiIHk9IjM5MSIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2MCIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLXdpZHRoPSIyIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiAxMThweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiA0MjFweDsgbWFyZ2luLWxlZnQ6IDJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPuWcsOWdgOS4iuaKpTwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSI2MSIgeT0iNDI1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5Zyw5Z2A5LiK5oqlPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMjQiPjxnPjxlbGxpcHNlIGN4PSIzNjEiIGN5PSIzNzEiIHJ4PSIyMCIgcnk9IjIwIiBmaWxsPSJyZ2IoMjU1LCAyNTUsIDI1NSkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiAzOHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDM3MXB4OyBtYXJnaW4tbGVmdDogMzQycHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij7lnLDlnYDliJfooag8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMzYxIiB5PSIzNzUiIGZpbGw9InJnYigwLCAwLCAwKSIgZm9udC1mYW1pbHk9IiZxdW90O0hlbHZldGljYSZxdW90OyIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7lnLDlnYDliJfooag8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIyNSI+PGc+PGVsbGlwc2UgY3g9IjQwMSIgY3k9IjM3MSIgcng9IjIwIiByeT0iMjAiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuNSAtMC41KSI+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5IiBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDM4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMzcxcHg7IG1hcmdpbi1sZWZ0OiAzODJweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPuaIkeeahElEPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjQwMSIgeT0iMzc1IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSImcXVvdDtIZWx2ZXRpY2EmcXVvdDsiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5oiR55qESUQ8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIyNiI+PGc+PHJlY3QgeD0iMSIgeT0iNDkxIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjYwIiBmaWxsPSJyZ2IoMjU1LCAyNTUsIDI1NSkiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2Utd2lkdGg9IjIiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuNSAtMC41KSI+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5IiBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDExOHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDUyMXB4OyBtYXJnaW4tbGVmdDogMnB4OyI+PGRpdiBkYXRhLWRyYXdpby1jb2xvcnM9ImNvbG9yOiByZ2IoMCwgMCwgMCk7ICIgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IHJnYigwLCAwLCAwKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgb3ZlcmZsb3ctd3JhcDogbm9ybWFsOyI+562J5b6F5pWw5o2uPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjYxIiB5PSI1MjUiIGZpbGw9InJnYigwLCAwLCAwKSIgZm9udC1mYW1pbHk9IiZxdW90O0hlbHZldGljYSZxdW90OyIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7nrYnlvoXmlbDmja48L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PHN3aXRjaD48ZyByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiLz48YSB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC01KSIgeGxpbms6aHJlZj0iaHR0cHM6Ly93d3cuZHJhd2lvLmNvbS9kb2MvZmFxL3N2Zy1leHBvcnQtdGV4dC1wcm9ibGVtcyIgdGFyZ2V0PSJfYmxhbmsiPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTBweCIgeD0iNTAlIiB5PSIxMDAlIj5UZXh0IGlzIG5vdCBTVkcgLSBjYW5ub3QgZGlzcGxheTwvdGV4dD48L2E+PC9zd2l0Y2g+PC9zdmc+

relay_service字段说明:

如果本节点实现了中继服务,在这个对象中公布自己

  • name: 中继节点名称,自定义
  • listen_addr: 监听的地址
  • peers_max: 最大负载连接数
  • peers_current: 当前负载连接数
  • 请求示例
json
{
  "id": "8dBGekdM7dJ6fcrDVcQYap95S68w5HNrS86ge3jjdJsJ",
  "public_key": "约580长度的字符串,hex格式",
  "listen_addr": [
    {"type": "local", "address": "tcp://192.168.1.2:1888"},
    {"type": "local", "address": "udp://[fd00:ec60:73ed:8049:8afe:7c71:fe7d:33ab]:1888"},
    {"type": "externally", "address": "udp://110.110.110.110:32001"},
    {"type": "relay", "address": "udp://baidu.com:8001"}
  ],
  "relay_service": {
    "name": "公益-aliyun-1",
    "listen_addr": "tcp://aliyun-1.com:8000",
    "peers_max": 1000,
    "peers_current": 0
  },
  "time": 1730286096,
  "sign": "签名的十六进制字符串"
}
  • 返回说明
名称类型描述
msgstring响应消息
  • 返回示例
json
{
  "msg": "success"
}

地址解析

在我们连接到另一终端时,需要进行此项解析,将对方的ID解析为可通过TCP/IP通信的地址二元组。

  • 调用方法
http
GET {{urlPrefix}}/SL-A-1.0/peer/nslookup?id={{peerId}}
  • 参数说明
名称类型是否必需示例描述
idstringY"8dBGekdM7dJ6fcrDVcQYap95S68w5HNrS86ge3jjdJsJ"对等节点ID
  • 返回说明
名称类型描述
TODO-TODO
  • 返回示例
json
TODO

发现服务是可选的

  • 当你通过其他方式,例如nmbmDNSWS-DiscoveryUDP广播等方法获取了对端连接信息,那么你不需要使用发现服务,这提供了无互联网的情况下进行局域网连接的能力。

  • 地址上报是可选的

    当你只想联系他人,而无需被他人主动找到时,就无需上报地址,只需要解析地址即可

物联网设备通信协议文档