跳转到内容

Socket.IO API

Yunba 的 SDK 按照实现的方式,可以分为两种,一种是所谓原生 SDK,一种是基于 Socket.IO 的 SDK。

例如像 Android, iOS, C 等这些原生 SDK,实现了完整的二进制协议栈,在运算能力有限、带宽有限的平台上,可以很好地工作。

另外一类像 JavaScript SDK(非 node.js),就是基于 Socket.IO API 实现的。

相对于原生 SDK,基于 Socket.IO API 的 SDK 代码体积小,开发周期短,适合为小众语言快速开发 SDK。

Socket.IO 是在 WebSocket 基础上开发的一种基于 HTTP 协议的长连接通讯方式,使用起来跟原生的 Socket 一样方便, 特别是在 Web App 开发中,使用得越来越多。

这里以 Python 为例子,演示通过调用 Yunba Socket.IO API 快速集成。

Python 请使用 0.6.5 版本的 Socket.IO-client;Node.js 请使用 0.9.17 版本的 Socket.IO-client。

终端窗口
pip install -U socketIO-client==0.6.5

与云巴 Socket.IO 服务器建立连接。

socketIO = SocketIO('sock.yunba.io', 3000)
名称 类型 说明
host String Socket.IO API Server,默认值 ‘sock.yunba.io’。
port Number Socket.IO API 端口,默认值 3000。

注:

  1. 如obj.server中未指定https://或http://,Socket.IO-Client 会根据当前页面的协议, 选择使用 https 或 http 进行连接。在这种情况下,用户需要注意选择合适的port。使用 SSL/TLS 方式进行连接,则port为443;否则,port为3000。

  2. 如果想使用 SSL/TLS 方式连接,则obj.server请填写https://sock.yunba.io、port使用443。

  3. 免费用户可以试用 RESTful 和 Socket.IO 的加密链路,实际生产使用需要付费。

init()连接成功后的回调。

{"name":"socketconnectack","args":[{"msg":"socket.io connected"}]}
名称 类型 说明
msg String 连接信息。

获取到新消息的事件,获取到的消息的格式为{topic: topic, msg: msg}。

socketIO.on('message', {callback_function})
名称 类型 说明
topic String 收到消息的 topic/alias
msg String 收到消息的 内容

触发 connect 命令,与 Socket.IO 服务器确认身份。以下两种方式任选其一即可,推荐使用 AppKey + CustomID 方式进行连接,可保证每次连接都能使用相同的 Session。

socketIO.emit('connect_v2', {'appkey': '52fcc04c4dc903d66d6f8f92'}) # 使用 AppKey 进行连接
socketIO.emit('connect_v2', {'appkey': '52fcc04c4dc903d66d6f8f92', 'customid': 'userid'}) # 使用 AppKey 和自定义的会话 ID 进行连接
名称 类型 说明
appkey String 在云巴 Portal 申请到的应用的 AppKey。
customid String 用户自定义的会话 ID。

connect()成功后的回调。

{"name":"connack","args":[{"success":true}, {"sessionid": "567a4a754407a3cd028aaf6b-f02bf150-c653-4557-973f-8526b078d736"}]}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
sessionid String Session ID。

增加订阅一个 频道。成功订阅后,App 可以收到来自该频道的消息。新增订阅不会影响已有的订阅。

如需订阅某频道的 Presence,只需在频道名称的字符串末尾加上'/p'即可。详见下方示例。

# 订阅频道 testtopic1 的消息
socketIO.emit('subscribe', {'topic': 'testtopic1', 'messageId':'11833652203486491112'})
# 订阅频道 testtopic1 下的 Presence 消息
socketIO.emit('subscribe', {'topic': 'testtopic1/p', 'messageId':'11842355493944946011'})
名称 类型 说明
topic String App 订阅的频道。取值范围详见 参数说明。
messageId String 参数可选。指定的 Message ID。与 suback 回应中的 messageId 相对应。

subscribe()订阅成功后的回调。

{"name":"suback","args":[{"success":true},{"topic":"testtopic1"},{"messageId": "11833652203486491112"}]}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
topic String 订阅的频道名称。
messageId String Message ID。对应 subscribe() 时指定的 Message ID。如未指定,则系统会自动分配一个 ID。

取消对某个 频道 的订阅。成功取消后,就不会再收到来自该频道的消息。

socketIO.emit('unsubscribe', {'topic': 'testtopic1', 'messageId':'11833652203486491112'})
名称 类型 说明
topic String 取消订阅的频道。取值范围详见 参数说明。
messageId String 参数可选。指定的 Message ID。与 unsuback 回应中的 messageId 相对应。

unsubscribe()订阅成功后的回调。

{"name":"unsuback","args":[{"success":true}, {"topic":"testtopic1"}, {"messageId": "11833652203486491112"}]}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
topic String 取消订阅的频道名称。
messageId String Message ID。对应 unsubscribe() 时指定的 Message ID。如未指定,则系统会自动分配一个 ID。

向某个 频道 发布消息。成功发布后,所有订阅此频道的客户端都会收到消息。

socketIO.emit('publish', {'topic': 'channel1', 'msg': 'hello, Yunba', 'qos': 1})
名称 类型 说明
topic String App 订阅的频道。取值范围详见 参数说明。
msg String 发布的内容。
qos Number 服务质量等级。有三种取值:“0”表示最多送达一次;“1”表示最少送达一次;“2”表示保证送达且仅送达一次。默认为“1”。详见 QoS 的说明。

publish()、publish_to_alias()、publish2()和publish2_to_alias()成功的回调。

{"name":"puback","args":[{"success":true, "messageId": "11842355493944946011"}]}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
messageId String 消息 ID,与发布消息时的 ID 对应。如果发布时未指定,则云巴系统会生成一个 ID。

用来设置用户名,即绑定账号。每个用户只能指定一个 别名。

将set_alias()的alias参数设置为空字符串即可取消别名。

socketIO.emit('set_alias', {'alias': 'mytestalias1'})
名称 类型 说明
alias String 用户设置的别名信息,取值范围详见 参数说明。

set_alias()设置别名成功后的回调。

{"success": true}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。

获取当前用户的 别名。

socketIO.emit('get_alias')

get_alias()获取别名的回调。

{'alias': 'mytestalias1'}
名称 类型 说明
alias String 用户当前的别名。

向某个 别名 发布消息。发布成功后,该别名的客户端会收到消息。

socketIO.emit('publish_to_alias', {'alias': 'mytestalias1', 'msg': "hello to alias"})
名称 类型 说明
alias String 目标别名。取值范围详见 参数说明。
msg String 向目标别名发布的消息。

获取某 频道 下的所有订阅者的 别名 列表,别名个数及状态。

socketIO.emit('get_alias_list', {'topic': 'testtopic1'})
名称 类型 说明
topic String 目标频道。取值范围详见 参数说明。

get_alias_list()的回调。

# 成功
{'data': {'alias': ['mytestalias1'], 'occupancy': 1}, 'success': true}
# 失败
{'success': false, error_msg: 'Broker Error'}
名称 类型 说明
success Boolean 成功返回 true,否则返回 false。
data.alias List 订阅了该topic的alias的列表,success 为 true 时有效。
data.occupancy Number 订阅了该topic的alias个数,success 为 true 时有效。
error_msg String 错误信息,success 为 false 时有效。

查询用户订阅的 频道 列表。如果传入参数 alias,是获取目标用户(别名)的频道列表;如果不传入参数 alias,则是获取当前用户的频道列表。

socketIO.emit('get_topic_list', {'alias': 'mytestalias1'})
名称 类型 说明
alias String 目标别名,取值范围详见 参数说明。

get_topic_list()结果回调。

# 成功
{'data': {'topics': ['testtopic2']}, 'success': True}
# 失败
{'success': false, error_msg: 'Broker Error'}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
data.topics List 订阅的topic列表,success 为 true 时有效。
error_msg String 错误信息,success 为 false 时有效。

publish()的升级版本,支持更多参数。

socketIO.emit('publish2', {
'topic': 'topic1',
'msg': 'from publish2',
"opts": {
'qos': 1,
'apn_json': {"aps":{"sound":"bingbong.aiff","badge": 3, "alert":"douban"}}
'messageId': '11833652203486491113'
}
})
名称 类型 说明
topic String 目标频道。取值范围详见 参数说明。
msg String 向订阅者发布的消息。
opts Dict 可选项。参考publish2()扩展参数。

publish2()与publish2_to_alias()的扩展参数都是可选项。如果不填写参数,则publish2()/publish2_to_alias()的行为与publish()/publish_to_alias()相似,只有一点不同:publish()/publish_to_alias()会发送默认的 APN,而publish2()/publish2_to_alias()如果不填写 apn_json,则不会发送 APN。

名称 类型 说明
qos Number 服务质量等级。有三种取值:“0”表示最多送达一次;“1”表示最少送达一次;“2”表示保证送达且仅送达一次。默认为“1”。详见 QoS 的说明。
apn_json Dict 如果不填,则不会发送 APN。 APN 参考:Apple 官方文档 及云巴 相关文档。
messageId String 消息 ID,64 位整型数转化成 String。发布消息时可以指定,如果不填,则由系统自动生成。
time_to_live Number 用来设置 离线消息 保留多久。单位为秒(例如,3600 代表 1 小时),默认值为 3 天,最大不超过 15 天。

publish_to_alias()的升级版本,支持更多参数。

socketIO.emit('publish2_to_alias', {'alias': 'alias_mqttc_sub', 'msg': "hello to alias from publish2_to_alias"});
名称 类型 说明
alias String 目标别名。取值范围详见 参数说明。
msg String 向别名发布的消息。
opts Dict 可选项。参考publish2_to_alias扩展参数。

publish2()与publish2_to_alias()的扩展参数都是可选项。如果不填写参数,则publish2()/publish2_to_alias()的行为与publish()/publish_to_alias()相似,只有一点不同:publish()/publish_to_alias()会发送默认的 APN,而publish2()/publish2_to_alias()如果不填写 apn_json,则不会发送 APN。

名称 类型 说明
qos Number 服务质量等级。有三种取值:“0”表示最多送达一次;“1”表示最少送达一次;“2”表示保证送达且仅送达一次。默认为“1”。详见 QoS 的说明。
apn_json Dict 如果不填,则不会发送 APN。 APN 参考:Apple 官方文档 及云巴 相关文档。
messageId String 消息 ID,64 位整型数转化成 String。发布消息时可以指定,如果不填,则由系统自动生成。
time_to_live Number 用来设置 离线消息 保留多久。单位为秒(例如,3600 代表 1 小时),默认值为 5 天,最大不超过 15 天。

查询用户的在线状态。

socketIO.emit('get_state', {'alias': 'mytestalias1'})
名称 类型 说明
alias String 目标 别名。

get_state()的回调。

# 成功
{'data': 'online', 'success': true}
# 失败
{'success': false, error_msg: 'Broker Error'}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
data String 在线状态。在线为 online,离线为 offline。
error_msg String 错误信息,success 为 false 时有效。

recvack 是付费服务,免费用户可能无法正常使用。

第一个目标用户(且不是消息发布者)收到消息给服务器回复puback后,给消息发布者发送recvack,消息发布者通过这个通知,可以了解第一个收到消息的用户的 alias 和 时间戳。

recvack {u'data': u'{"timestamp":1411374510357,"alias":"alias_mqttc_sub"}', u'success': True, u'messageId': u'11839467508410466019'}
名称 类型 说明
success Boolean 成功返回 true,失败返回 false。
data.timestamp Number recvack 收到的时间戳,时区为 GMT。
data.alias String recvack 用户的 alias。
messageId String 消息 ID,与 publish 时的 ID 对应。

Python 例子 (socketIO-client==0.5.5)

from socketIO_client import SocketIO
import logging
logging.basicConfig(level=logging.INFO)
def on_socket_connect_ack(args):
print 'on_socket_connect_ack', args
socketIO.emit('connect_v2', {'appkey': '52fcc04c4dc903d66d6f8f92', 'customid': 'python_demo'})
def on_connack(args):
print 'on_connack', args
socketIO.emit('subscribe', {'topic': 'testtopic2'})
print "publish2_to_alias"
socketIO.emit('publish2_to_alias', {'alias': 'alias_mqttc_sub', 'msg': "hello to alias from publish2_to_alias"});
def on_puback(args):
print 'on_puback', args
if args['messageId'] == '11833652203486491112':
print ' [OK] publish with given messageId'
def on_suback(args):
print 'on_suback', args
socketIO.emit('publish', {'topic': 'testtopic2', 'msg': 'from python', 'qos': 1})
socketIO.emit('publish', {
'topic': 'testtopic2',
'msg': 'from python with given messageId',
'qos': 1,
'messageId': '11833652203486491112'
})
socketIO.emit('publish2', {
'topic': 't2thi',
'msg': 'from publish2',
"opts": {
'qos': 1,
'apn_json': {"aps":{"sound":"bingbong.aiff","badge": 3, "alert":"douban"}},
'messageId': '11833652203486491113'
}
})
socketIO.emit('set_alias', {'alias': 'mytestalias1'})
def on_message(args):
print 'on_message', args
def on_set_alias(args):
print 'on_set_alias', args
socketIO.emit('publish2', {
'topic': 'testtopic2',
'msg': 'from publish2',
"opts": {
'qos': 1,
'apn_json': {"aps":{"sound":"bingbong.aiff","badge": 3, "alert":"douban"}}
}
})
socketIO.emit('get_alias')
socketIO.emit('publish_to_alias', {'alias': 'mytestalias1', 'msg': "hello to alias"})
socketIO.emit('get_topic_list', {'alias': 'mytestalias1'})
socketIO.emit('get_state', {'alias': 'mytestalias1'})
def on_get_alias(args):
print 'on_get_alias', args
def on_alias(args):
socketIO.emit('get_alias_list', {'topic': 'testtopic2'})
print 'on_alias', args
def on_get_topic_list_ack(args):
print 'on_get_topic_list_ack', args
def on_get_alias_list_ack(args):
print 'on_get_alias_list_ack', args
def on_publish2_ack(args):
print 'on_publish2_ack', args
if args['messageId'] == '11833652203486491113':
print ' [OK] publish2 with given messageId'
def on_publish2_recvack(args):
print 'on_publish2_recvack', args
def on_get_state_ack(args):
print 'on_get_state_ack', args
socketIO = SocketIO('sock.yunba.io', 3000)
socketIO.on('socketconnectack', on_socket_connect_ack)
socketIO.on('connack', on_connack)
socketIO.on('puback', on_puback)
socketIO.on('suback', on_suback)
socketIO.on('message', on_message)
socketIO.on('set_alias_ack', on_set_alias)
socketIO.on('get_topic_list_ack', on_get_topic_list_ack)
socketIO.on('get_alias_list_ack', on_get_alias_list_ack)
socketIO.on('puback', on_publish2_ack)
socketIO.on('recvack', on_publish2_recvack)
socketIO.on('get_state_ack', on_get_state_ack)
socketIO.on('alias', on_alias) # get alias callback
socketIO.wait()