1. 程式人生 > 實用技巧 >Swoole WebSocket 服務端如何主動推送訊息?

Swoole WebSocket 服務端如何主動推送訊息?

最近有個朋友在使用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