最近有個朋友在使用swoole做一個在線看球賽的功能,球賽數據是實時更新的;
要實現的是用戶在瀏覽網頁自動更新球賽數據(數據源是一個三方機構提供的,明確上線3秒請求一次);
解決方案:
1.輪詢:
客戶端定時請求服務端接口(服務端再請求第三方接口);
大概就是這樣一個流程;雖然流程和邏輯簡單,但是負載大、並且用戶看到的結果可能是不一致的;
1.swoole websocket方案:
服務端定時請求接口,如果數據有更新,則主動推送到客戶端實時修改數據即可;
swoole大致就是這樣一個簡單的流程;邏輯簡單,負載小,並且用戶看到的結果都是一致的;
下面是我寫的一個簡單的deomo:
服務端代碼:
<?php // +---------------------------------------------------------------------- // | Created by [ PhpStorm ] // +---------------------------------------------------------------------- // | Copyright (c) 2006-2016. // +---------------------------------------------------------------------- // | Create Time (11:40 PM) // +---------------------------------------------------------------------- // | Author: phpbloger // +---------------------------------------------------------------------- $ws = new Swoole\WebSocket\Server("0.0.0.0", 9501); //監聽WebSocket連接打開事件 $ws->on('open', function ($ws, $request) { var_dump($request->fd, $request->get, $request->server); $ws->push($request->fd, "hello, welcome\n"); }); //監聽WebSocket消息事件 $ws->on('message', function ($ws, $frame) { $data = explode('|',$frame->data); $ws->push($frame->fd, "server: {$frame->data}"); foreach ($ws->connections as $fd){ $ws->push($fd, '用戶'.$data[0].'說:'.$data[1]); } }); //利用swoole的定時器,定時請求第三方接口,將數據實時推送到客戶端即可;timer的簡單用法 $ws->on('WorkerStart', function ($ws, $worker_id){ Swoole\Timer::tick(3000, function (int $timer_id, $ws) { echo "timer_id #$timer_id, after 3000ms.\n"; foreach ($ws->connections as $fd){ $rand = mt_rand(0,9999); $ws->push($fd, '用戶'.$rand); } }, $ws); }); //監聽WebSocket連接關閉事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed\n"; }); $ws->start();
客戶端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <style> #message{ border: 1px solid #ccc; width: 100%; height: 200px;overflow: auto;} #conent{ width: 100%; height: 50px; border: 1px solid #ccc;} .main{margin-top: 10px;} #sendMessage{ width: 100%; border: 1px solid #ccc; background: blue; color: #fff; padding: 10px; font-weight: bold; font-size: 16px;} </style> <div> <h1>聊天室</h1> <div id="message"> </div> <div class="main"> <textarea id="conent"></textarea> <button id="sendMessage" onclick="sendMessage()">發送消息</button> </div> </div> <script src="/static/js/jquery-3.3.1.min.js"></script> <script> var username = 'user_'+Math.random(); var wsServer = 'ws://127.0.0.1:9501'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); }; websocket.onclose = function (evt) { console.log("Disconnected"); }; function sendMessage(){ var content = document.getElementById('conent').value; if(content == ''){ alert('請輸入聊天內容'); return; } //|作為數據包分割線 var text = username+'|'+content; websocket.send(text); } //監聽服務端回推的消息 websocket.onmessage = function (evt) { var message = evt.data; var html = '<p>'+message+'</p>'; $("#message").append(html); //成功將發送置空 document.getElementById("conent").value = ""; }; websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); }; </script> </body> </html>
轉載於:https://www.phpbloger.com/article/421.html