zoukankan      html  css  js  c++  java
  • 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 SwooleWebSocketServer("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
    ");
    });
    
    //监听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){
        SwooleTimer::tick(3000, function (int $timer_id, $ws) {
            echo "timer_id #$timer_id, after 3000ms.
    ";
            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
    ";
    });
    
    
    $ws->start();

     客户端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <style>
        #message{ border: 1px solid #ccc;  100%; height: 200px;overflow: auto;}
        #conent{  100%; height: 50px; border: 1px solid #ccc;}
        .main{margin-top: 10px;}
        #sendMessage{  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

  • 相关阅读:
    字体
    当前li的同级且不包含当前li
    溢出用省略号显示
    .NET Core中使用Cookie步骤
    .NET Core中使用Session步骤
    asp.net core 读取配置
    Asp.Net Core run on Ubuntu
    .net core中使用GB2312编码
    ubuntu mysql 安装
    samba的安装
  • 原文地址:https://www.cnblogs.com/houdj/p/13440352.html
Copyright © 2011-2022 走看看