# 訂閱/發布
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
- 單元測試