# 订阅/发布
SD框架提供了一个集群的订阅发布功能,实现和MQTT订阅发布一致。
* addSub($topic)
* removeSub($topic)
* sendPub($topic, $data, $destroy = true)
首先订阅信息是保留在服务器内存中,重启服务器后订阅的主题会全部清空。
如果用户想实现群组功能,订阅与发布只能作为通讯的基础服务,流程如下。
* A用户加入了a,b,c三个群组,服务器需要负责将A的群组关系落地。
* 通过addSub为A用户订阅a,b,c三个群组对应的主题名
* A用户上线需要重新为其订阅a,b,c三个群组对应的主题名
* 订阅与发布服务并不知道群里有多少人它只负责订阅与发布,其余需要自己实现
* 可以通过主题通配符实现特殊订阅
## 主题名和主题过滤器 Topic Names and Topic Filters
### 主题通配符 Topic wildcards
主题层级(topic level)分隔符用于将结构化引入主题名。如果存在分隔符,它将主题名分割为多个主题层级 topic level 。
订阅的主题过滤器可以包含特殊的通配符,允许你一次订阅多个主题。
主题过滤器中可以使用通配符,但是主题名不能使用通配符。
### 主题层级分隔符 Topic level separator
斜杠(‘/’ U+002F)用于分割主题的每个层级,为主题名提供一个分层结构。当客户端订阅指定的主题过滤器包含两种通配符时,主题层级分隔符就很有用了。主题层级分隔符可以出现在主题过滤器或主题名字的任何位置。相邻的主题层次分隔符表示一个零长度的主题层级。
### 多层通配符 Multi-level wildcard
数字标志(‘#’ U+0023)是用于匹配主题中任意层级的通配符。多层通配符表示它的父级和任意数量的子层级。多层通配符必须位于它自己的层级或者跟在主题层级分隔符后面。不管哪种情况,它都必须是主题过滤器的最后一个字符。
> 非规范评注
例如,如果客户端订阅主题 “sport/tennis/player1/#”,它会收到使用下列主题名发布的消息:
“sport/tennis/player1”
“sport/tennis/player1/ranking”
“sport/tennis/player1/score/wimbledon”
> 非规范评注
* “sport/#”也匹配单独的 “sport” ,因为 # 包括它的父级。
* “#”是有效的,会收到所有的应用消息。
* “sport/tennis/#”也是有效的。
* “sport/tennis#”是无效的。
* “sport/tennis/#/ranking”是无效的。
### 单层通配符
加号 (‘+’ U+002B) 是只能用于单个主题层级匹配的通配符。
在主题过滤器的任意层级都可以使用单层通配符,包括第一个和最后一个层级。然而它必须占据过滤器的整个层级。可以在主题过滤器中的多个层级中使用它,也可以和多层通配符一起使用。
> 非规范评注
例如, “sport/tennis/+” 匹配 “sport/tennis/player1” 和 “sport/tennis/player2” ,
但是不匹配 “sport/tennis/player1/ranking” 。
同时,由于单层通配符只能匹配一个层级, “sport/+” 不匹配 “sport” 但是却匹配 “sport/”。
> 非规范评注
* “+” 是有效的。
* “+/tennis/#” 是有效的。
* “sport+” 是无效的。
* “sport/+/player1” 也是有效的。
* “/finance” 匹配 “+/+” 和 “/+” ,但是不匹配 “+”。
## 主题语义和用法 Topic semantic and usage
主题名和主题过滤器必须符合下列规则:
* 所有的主题名和主题过滤器必须至少包含一个字符。
* 主题名和主题过滤器是区分大小写的。
* 主题名和主题过滤器可以包含空格。
* 主题名或主题过滤器以前置或后置斜杠 “/” 区分。
* 只包含斜杠 “/” 的主题名或主题过滤器是合法的。
* 主题名和主题过滤器不能包含空字符 (Unicode U+0000) 。
* 主题名和主题过滤器是UTF-8编码字符串,它们不能超过65535字节。
*
除了不能超过UTF-编码字符串的长度限制之外,主题名或主题过滤器的层级数量没有其它限制。
匹配订阅时,服务端不能对主题名或主题过滤器执行任何规范化(normalization)处理,不能修改或替换任何未识别的字符 。
主题过滤器中的每个非通配符层级需要逐字符匹配主题名中对应的层级才算匹配成功。
> 非规范评注
使用UTF-8编码规则意味着,主题过滤器和主题名的比较可以通过比较编码后的UTF-8字节或解码后的Unicode字符。
> 非规范评注
* “ACCOUNTS” 和 “Accounts” 是不同的主题名。
* “Accounts payable” 是合法的主题名
* “/finance” 和 “finance” 是不同的。
如果订阅的主题过滤器与消息的主题名匹配,应用消息会被发送给每一个匹配的客户端订阅。主题可能是管理员在服务端预先定义好的,也可能是服务端收到第一个订阅或使用那个主题名的应用消息时动态添加的。服务端也可以使用一个安全组件有选择地授权客户端使用某个主题资源。
- Introduction
- SD 3.X文档连接
- 导言
- 用户案例
- 基于Swoole扩展分布式全栈开发框架
- 选择SD框架助力企业开发
- 捐赠SwooleDistributed项目
- 框架性能报告
- 更新日志
- VIP服务福利
- 安装与配置
- 【推荐】全自动安装部署
- 环境要求
- 使用Composer安装/更新SD框架
- 通过Docker安装
- 代码结构
- 启动命令
- 服务器配置
- 服务器基础配置server.php
- 客户端协议配置client.php
- business.php
- log.php
- 微服务及集群配置consul.php
- fileHeader.php
- mysql.php
- redis.php
- 定时任务配置timerTask.php
- 服务器端口配置ports.php
- catCache.php
- 验证服务启动成功
- 微服务-Consul
- 日志工具-GrayLog
- 集群-Cluster
- 内核优化
- 入门教学
- 开发流程
- 开发前必读
- 开发规范
- 基本流程
- 框架入口
- Model数据模型
- Controller控制器
- 协程
- 协程基础
- 迭代器
- 调度器
- 使用协程的优势
- 通过协程的方法屏蔽异步同步的区别
- Select多路选择器
- 协程Sleep
- 通用协程方法
- 设置超时
- 设置无异常
- 设置降级函数
- initAsynPools
- dump
- 封装器与路由器
- 封装器
- sendToUid
- 路由器
- sendToUids
- 对象池
- 扩展组件
- 中间件
- Redis使用介绍
- RedisAsynPool
- Redis具体使用
- sendToAll
- RedisRoute
- Redis+Lua
- Mysql使用介绍
- MysqlAsynPool
- Mysql返回值
- 如何获取构建的mysql语句
- 如何执行一个SQL
- 如何执行事务
- stopTask
- Mysql具体使用
- 异步客户端
- Loader
- MqttClient
- model
- SdTcpRpcPool
- task
- HttpClientPool
- view
- TcpClientPool
- AMQP
- initialization
- Memory
- destory
- Cache
- Lock
- Pool
- EventDispatcher
- Process
- Cluster
- TimerTask
- Reload
- Consul
- Context
- 自定义进程
- 进程间RPC
- $http_input
- CatCache
- $http_output
- TimerCallBack
- 专题
- HTTP专栏
- TCP专栏
- 基础知识
- WebSocket专栏
- 微服务
- Consul配置
- RPC
- REST
- AMQP异步任务系统
- MQTT简易服务器
- Docker化以及资源编排
- 快速搭建公司内部统一的开发环境
- 使用HTTPS/WSS
- 订阅/发布
- 游戏专题
- 类介绍
- AppServer
- clearState
- onOpenServiceInitialization
- SwooleDistributedServer
- get_instance
- kickUid
- bindUid
- unBindUid
- coroutineUidIsOnline
- coroutineCountOnline
- setTemplateEngine
- isWebSocket
- isTaskWorker
- getSocketName
- initAsynPools
- addAsynPool
- getAsynPool
- getServerAllTaskMessage
- Controller
- onExceptionHandle
- send
- sendToUid
- sendToUids
- sendToAll
- sendToGroup
- close
- getContext
- defaultMethod
- $redis_pool
- $mysql_pool
- $request_type
- $fd
- $uid
- $client_data
- $request
- $response
- $loader
- $logger
- $server
- $config
- Model
- initialization
- destory
- View
- Task
- stopTask
- HttpInput
- postGet
- post
- get
- getPost
- getAllPostGet
- getAllHeader
- getRawContent
- cookie
- getRequestHeader
- server信息
- getRequestMethod
- getRequestUri
- getPathInfo
- HttpOutput
- setStatusHeader
- setContentType
- setHeader
- end
- setCookie
- endFile
- 单元测试