1.現實情況
我們在做商城系統的過程當中,會要求做一個訂單提醒的功能,即來新的訂單會提醒。我實作的方法是有訂單後就會提醒“您有新的訂單,請注意查收!”
2.解決方案
2.1ajax輪詢
輪詢的方法比較簡單,就是每過多少秒發起一次請求。如果項目中的訂單不多,每隔多少秒發一次請求會對伺服器有挺大的壓力。我将輪詢關鍵的代碼貼出來,僅供參考。
<script>
setInterval("order()",59000000);//每59秒重新整理查詢一次
var last_count = {$count};
function order() {
var data = {
'last_count':last_count
};
$.ajax({
type: "POST",
data: data,
url: "{:url('Order/sendOrderNotice')}",//背景方法
timeout: 60000,
cache: false,
async: false,
dataType: "json",
success: function(data) {
if(data.status == 1){
var audio = document.getElementById( "play" ); //浏覽器支援 audio
audio.play(); //播放提示音
last_count = data.last_count;
setTimeout(function(){
window.location.reload();
}, 3000);
}
}
});
}
</script>
上面就是這個解決方案的核心。後端的代碼請根據自己的業務邏輯編寫。
2.2 結合workerman實作
這個方法是我比較推薦的。利用了workerman編寫一段推送架構。具體參考:
https://www.workerman.net/web-sender
3.準備工作
下載下傳workerman。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL6lEVPJzZU5keJpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5YDO4UjNwUTMxAzNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
上圖是下載下傳好的包。點選start_for_win.bat。
出現這個表示服務啟動了。
4.解決過程
訂單監控頁面端的代碼:
<script src='http://cdn.bootcss.com/socket.io/1.3.7/socket.io.js'></script>
<script src="https://g.csdnimg.cn/??lib/jquery/1.12.4/jquery.min.js"></script>
<script>
// 連接配接服務端,workerman.net:2120換成實際部署web-msg-sender服務的域名或者ip
var socket = io('http://www.tp5_test.com:2120'); //http://www.tp5_test.com換成自己的域名或者ip
// uid可以是自己網站的使用者id,以便針對uid推送以及統計線上人數,這個ID可以随便寫
uid = 1557062581000;
// socket連接配接後以uid登入
socket.on('connect', function(){
socket.emit('login', uid);
});
<!--// 後端推送來消息時-->
socket.on('new_msg', function(msg){
//兩種處理方式
// 1 追加到頁面元素中,可以做成頁面的彈窗
$("#msg").append(msg);
//2 播放提示應 :
if(msg == 1){
var audio = document.getElementById( "play" ); //浏覽器支援 audio
audio.play(); //播放提示音
}
});
// 後端推送來線上資料時
socket.on('update_online_count', function(online_stat){
console.log(online_stat);
});
</script>
後端代碼:
//這個方法我随便寫了寫,具體的處理就是在支付完成回調以後,用用send_workerman方法就可以了。我是用sends來模型支付完成以後的回調
public function sends($id)
{
// var_dump($id);die;
if($id == 1){
$this->send_workman($id);
}else{
echo '沒有發送消息';
}
}
/**
* @route('send_workman')
*/
public function send_workman($id)
{
$to_uid = '1557062581000'; //和頁面的uid一緻,不填寫也可以
// 推送的url位址,使用自己的伺服器位址
$push_api_url = "http://www.tp5_test.com:2121/";
$post_data = array(
"type" => "publish",
"content" => $id,
"to" => $to_uid,
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $push_api_url );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array("Expect:"));
$return = curl_exec ( $ch );
curl_close ( $ch );
var_export($return);
}
5.總結
兩種方式都可以使用,推薦使用第二種,代碼已經經過測試無問題。如果幫助到你的話,那就很棒了。如果有什麼疑問的話,可以給我發郵件:[email protected]。我盡量答複。