美文网首页
swoole解决服务端主动向客户端推送问题

swoole解决服务端主动向客户端推送问题

作者: echomaple | 来源:发表于2020-07-01 16:25 被阅读0次

    前期,写过一个帖子,为了解决微信支付成功之后,异步回调问题,使用了workerman的web-sender,其中需要引入大量文件开启三个端口,现阶段改进一下,原理利用swoole的websocket继承了Swoole\Http\Server,可以使用后者的onrequest接收其他页面后端页面的主动推送,原理大概如下,首先是start.php,主要作用是开启守护进程,并且执行调用thinkphp5的test.php中的方法

    <?php

    include_once('/www/wwwroot/tp5/extend/sw/Test.php');

    $serv = new sw\Test("0.0.0.0", 9501);

    $serv->set(array(

        'daemonize'      => 0,

        'worker_num'      => 2,

        'task_worker_num' => 2

    ));

    $redis= '';

    $serv->on('WorkerStart', function ($serv, $worker_id) {

        global $redis;

        $redis = new \Redis();

        $redis->connect("127.0.0.1", 6379) || die("redis 连接失败");

        echo "redis 连接成功!\n";

    });

    $serv->on('Open', function($serv, $frame) {

        echo "链接成功";

    });

    //当收到用户的消息时 触发事件

    $serv->on('Message', function($serv, $frame) {

        global $redis;

        var_dump($frame);

        $serv->messaging($redis,$frame);

    });

    $serv->on('request', function(\Swoole\Http\Request $request, \Swoole\Http\Response $response) {

        global $serv;

        if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {

            $response->end();

            return;

        }

        $serv->push($request->get['a'],$request->get['b']);

        return;

    });

    $serv->on('Task',function(){


    });

    $serv->on('finish',function(){


    });

    $serv->start();

    ?>

    linux服务器下,切到start.php目录,执行 php start.php &

    以守护进程方式执行,出现如下,即表示开启9501端口成功

    其次是Test.php,路径在extend文件夹下,代码如下

    <?php

    namespace sw;

    class Test extends \Swoole\WebSocket\Server

    {

      public function messaging(\Redis $redis,$frame){

          var_dump($frame->data);

          $redis->setex($frame->data,1000,$frame->fd);

          echo 'sucess-setredis';

      }

    }

    redis存储订单号作为redis的string键值,frame的fd作为值

    其次,在微信异步回调结尾处,写上如下方法即可,

    $orderid = input('a'); //订单号

                $redis = new \Redis();

                $redis->connect("127.0.0.1", 6379);

                $a = $redis->get($orderid); //此时a为客户端id,可以推送到指定用户

                file_get_contents('http://121.37.158.*:9501?a='.$a.'&b='.$orderid);//换成自己的ip,会失败,但是不用理会

    其中file_get_contents可以换成自己的curl,更好一点,直接执行会失败,不用管,其实已经推送成功了,

    前端js中加入如下方法

    <script>

    var wsObj = new WebSocket("ws://*.*.*.*:9501"); //换成自己的ip

        wsObj.onopen = function(){  //发送请求

            alert("open");

            wsObj.send("a123");

        };

        wsObj.onmessage = function(ev){  //获取后端响应

            //获取到推送的数据,处理业务逻辑,可以进行跳转到成功页面

            alert(ev.data);

        };

        wsObj.onclose = function(ev){

            alert("close");

        };

        wsObj.onerror = function(ev){

            alert("error");

        };

    </script>

    其中onmessage 处理接收数据。

    end:至于为何使用redis,是因为我想用tp5的Db方法,却不知道该如何在Test.php中使用,在Test.php中使用会报错方法不存在,如果你有好的方法可以使用数据库操作,敬请指点。

    PS:: 2020-07-01,生活不易,可能说不准哪天就失业了,但是a za a za fighting。

    相关文章

      网友评论

          本文标题:swoole解决服务端主动向客户端推送问题

          本文链接:https://www.haomeiwen.com/subject/wtqhqktx.html