昨晚我躺在牀上,百無聊賴地翻閱 阿蘭·德波頓《身份的焦慮》這本書,看到這麼一段話,讓我想起網絡上作牆頭草的鍵盤俠,他們喜歡貼標籤,而後去簡單粗暴地批評或討好一類人,那麼能夠說公衆的眼睛是雪亮的嗎?我一直不喜歡太絕對太確定的觀點,對此我也保留懷疑,包括那些道聽途說來的道理。php
公共輿論的缺陷,究其緣由,在於公衆不肯意將本身的觀點交由理性分析進行推敲,而是將本身的觀點創建在直覺、感情和習俗之上。web
我常常在早餐出門上班的時候,會在微信小程序點一份麥當勞6元實惠早餐(酸菜雞肉粥+薯餅),而後路過的時候,順路取餐。redis
可是我最近發現,麥當勞提供了 選擇取餐時間的服務。而後在對應的時間推進信息,提醒用戶取餐。數據庫
這麼作有兩個好處小程序
保證客戶食物的新鮮微信小程序
工做人員可按照時間去處理訂單微信
emmm 我以爲這是個好的商業idea。websocket
在吃完這份早餐,我就想,要不用代碼實現一個這個功能的demo吧。swoole
主要的工具網絡
swoole的websocket 服務端
swoole的異步毫秒定時器
redis 的有序集合
若是是在微信開發的話,其實調用一下微信的模板信息接口,進行消息推送。swoole_timer_after
函數是一個一次性定時器,執行完成後就會銷燬。此函數與PHP
標準庫提供的sleep
函數不一樣,after
是非阻塞的。而sleep
調用後會致使當前的進程進入阻塞,將沒法處理新的請求。
使用redis 的有序集合能夠的實現按照取餐時間排序的隊列結構(圖我本身畫的),這裏我怕同一秒內有多個用戶下單,併發形成隊列的覆蓋,我選用了php獲取毫秒的內置函數()
microtime(true)//必定要加上ture才能返回浮點數據
餐廳的工做人員可按照上面的列表來
服務端生產隊列和異步推送信息的代碼實現
1 <?php 2 /** 3 * Created by PhpStorm. 4 * User: 印第安老斑鳩 5 * Date: 2019/2/14 6 * Time: 10:30 7 */ 8 $server = new swoole_websocket_server("0.0.0.0",9501); 9 $server->set(array( 10 'worker_num'=>2, 11 )); 12 $redis = new redis(); 13 $redis->connect('127.0.0.1', 6379); 14 $server->on('open', function (Swoole\WebSocket\Server $server, $request) {}); 15 $server->on('message', function (Swoole\WebSocket\Server $server, $frame) use ($redis){ 16 //將任務安裝時間丟進redis的有序集合之中(實際上要同步存進數據庫) 17 $result = $redis->zAdd('queue',microtime(true),'用戶user'.time()); 18 if ($result){ 19 swoole_timer_after($frame->data,function () use($frame,$server){ 20 //作異常捕獲,失敗的話就通知失敗 21 try{ 22 $str = "你好,你在".(($frame->data)/1000).'秒前的預約的套餐,請到店內櫃檯前拿取'; 23 $server->push($frame->fd,$str); 24 }catch (Exception $exception){ 25 $server->push($frame->fd,'訂單失敗'); 26 } 27 }); 28 } 29 $server->push($frame->fd,"支付成功。請稍後,接收通知!"); 30 }); 31 $server->on('close', function ($ser, $fd) { 32 echo "client {$fd} closed\n"; 33 }); 34 $server->start();
定時任務消費隊列的代碼實現:
<?php /** * Created by PhpStorm. * User: 印第安老斑鳩 * Date: 2019/2/15 * Time: 12:07 */ $redis = new Redis(); $redis->connect('localhost',6379); //3秒鐘查詢一次任務隊列 swoole_timer_tick(3000,function ()use($redis){ $result = $redis->zRange('queue',0,-1); if($result){ foreach ($result as $res){ $redis->zRem("queue", $res); echo "隊列中的".$res."的訂單已經處理完畢\n"; } }else{ echo "目前沒有隊列訂單任務"; } });
測試結果:我建立了websocket 服務,端口是9501
啓動隊列的消費的進程,結果:
ok,就這麼一個demo搞定!但並不能投放於工業生產。
微信公衆號: