與硬件設備鏈接通信(定位設備)git
IM系統(用於直播頁面的聊天通信)github
說明:
須要將全部的定位設備實時的接收,將實時的軌跡記錄顯示在地圖上web
注意點:
第一點:
web1服務器 鏈接的用戶1,2,3,web1廣播信息時只能廣播用戶1,2,3,不能廣播web2鏈接的用戶4,5,6,假設場景是聊天,用戶1發送一消息,只有web1 服務器的用戶能看到,web2的用戶所有不能收到redis
第二點:消息的頻率控制,例:100個設備,100個用戶, 100個設備每秒上傳一條數據,須要實時廣播給每一個用戶,就是每秒要100*100 = 1W次,因此能夠彙總每秒數據廣播給全部用戶等等方法數據庫
數據傳輸的流程圖:
不包含業務邏輯,將web1,web2,接收的消息彙總而後再廣播給web1,web2,再廣播給用戶服務器
說明:須要把全部的定位設備上傳的數據入庫,設備7個,每秒一條數據,我的使用swoole 的task 函數(投遞一個異步的任務到 task_worker池中,此函數是非阻塞的, worker進程數一樣能夠配置) 後調用接口方式入庫swoole
服務器內存報警問題網絡
緣由: 在於swoole_server->task 函數
官方介紹task底層使用Unix Socket管道通訊,是全內存的,沒有IO消耗。單進程讀寫性能可達100萬/s,不一樣的進程使用不一樣的管道通訊,能夠最大化利用多核。框架
但這任務若是是調用程序接口時,因爲網絡的延遲,增長的任務大於消費的任務時,內存佔用會不斷的增長,致使服務器的內存被佔滿。異步
解決方法:消息針對入任務的頻率控制,能夠根據本身的業務場景定義這個時間與是否可延遲等狀況,彙總1秒內的全部數據再調用程序接口(彙總時我的使用redis),最好能直接入庫,沒必要調用接口
簡單代碼片斷,不全(供初學者瞭解,官方網站demo類似)
function __construct($config) { $this->config = $config; $this->serv = new Swoole\Server($config['server']['host'], $config['server']['port']); // 鏈接redis $this->redis = new Predis\Client($config['redis']); $this->storage = new Storage($this->config); $this->serv->set([ 'worker_num' => $this->config['server']['workerNum'], //工做進程數量 'daemonize' => $this->config['server']['daemonize'], //是否做爲守護進程 'task_worker_num' => $this->config['server']['taskWorkerNum'], ]); $this->serv->on('connect', function ($serv, $fd){ $this->onConnect($fd, $serv); }); $this->serv->on('receive', function ($serv, $fd, $from_id, $data) { $this->onReceive($fd, $serv, $data); }); $this->serv->on('Close', function($server, $fd) { $this->onClose($fd, $server); }); $this->serv->on('Task', function($server, $task_id, $from_id, $data) { $this->onTask($server, $task_id, $from_id, $data); }); $this->serv->on('Finish', function($server, $task_id, $data) { $this->onFinish($server, $task_id, $data); }); $this->serv->start(); } public function onTask($serv, $task_id, $from_id, $data){ // insert 方法是經過接口入庫 $this->storage->insert($data); } public function onReceive($fd, $serv, $data) { $this->storage->writeLog('message:'.$data); $data = $this->formatData($data, $fd); $serv->task($data); } public function onClose($fd, $serv) { // writeLog 方法是寫入log $this->storage->writeLog('close fd:'.$fd); } public function onFinish($serv, $task_id, $data) { return ''; }
參考官方github: webim系統.
官方wiki: swoole 框架wiki
好處
封裝了數據庫的model類,數據庫的ORM接口
redis的封裝,能夠實現多實例訪問
框架有一些經常使用的方法,像log 等等(我只用到了log)
webim 官方有demon,能夠參考
壞處:
文檔特別不全,一個簡單的實現會折騰半天