yii2连接websocket服务实现服务端主动推送消息给客户端

上一篇写的是websocket的服务,这一篇写写调用服务和web端调用,接收消息部分

 1、调用websocket服务,主动推送消息的方法

<?php
namespace \common\services;

use common\helpers\EnvHelper;
use WebSocket\BadOpcodeException;
use WebSocket\Client;
use yii\base\Exception;
use yii\console\Controller;

class WebSocketService extends Controller
{
    /**
     * Param: 通过user_id,推送消息
     * @return void
     * @throws Exception
     */
    public static function sendMsg($user_id,$price)
    {
        if(!empty($user_id)){
            $uri = 'wss://' . EnvHelper::get('WEBSOCKET_URL');
            $ws  = new Client($uri);
            try {
                $data = [
                    'user_id' =>$user_id,
                    'type'=>'WEBSOCKET_URL',
                    'msg' =>"您好,{$price}"
                ];
                $ws->send(json_encode($data,JSON_UNESCAPED_UNICODE));
                return "发送成功\n";
                usleep(100);
            } catch (BadOpcodeException $e) {
                throw new Exception($e->getMessage());
            }
            $ws->close();
        }
    }
}

2、在job中加入编写任务

<?php

namespace common\jobs;


/**
 * Param: 推送消息给
 * Class SendMsgJob
 */
class SendMsgJob extends \yii\base\BaseObject implements \yii\queue\JobInterface
{
    public $user_id;
    public $price;

    /**
     * @inheritdoc
     */
    public function execute($queue)
    {
        try {
            $res = WebSocketSendService::sendMsg($this->user_id,$this->price);
            \Yii::$app->byfLog->channel('WebSocket')->info('推送消息给:'.$res);
        }catch (\Exception $exception){
            \Yii::$app->byfLog->channel('WebSocket')->error('推送消息错误'.$exception->getFile() . ':' . $exception->getLine() . ':' . $exception->getMessage() . PHP_EOL);
        }
    }
}

 3、推送消息加入异步队列:

<?php
namespace console\controllers;

use addons\ByShop\common\exceptions\ShopException;
use common\services\WebSocketSendService;
use WebSocket\BadOpcodeException;
use yii\base\Exception;
use yii\console\Controller;

class WebSocketPushController extends Controller
{
    /**
     * Param: 通过user_id,推送消息给
     * @param $user_id
     * @return void
     * @throws Exception
     */
    public function actionSendMsg($user_id,$price)
    {
        try {
            WebSocketSendService::sendMsg($user_id,$price);
        } catch (BadOpcodeException $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * Param: 推送消息任务加入队列
     * @param $user_id
     * @param $price
     * @return void
     * @throws Exception
     */
    public function actionSendMsgJob($user_id,$price)
    {
        try {
            //$this->user_id,$this->price
            \Yii::$app->queue->bind('websocket-job')->push(new SendMsgJob(['user_id' => $user_id,'price'=>$price]));
        } catch (BadOpcodeException $e) {
            throw new Exception($e->getMessage());
        }
    }

}

 手动推送消息任务队列测试的命令:

php yii web-socket-push/send-msg-job 112402 4.9999

4、web端连接websocket服务,实现接收消息

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script type="text/javascript">

        //获取url中的参数
        function getUrlParam(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
            var r = window.location.search.substr(1).match(reg);  //匹配目标参数
            if (r != null) return unescape(r[2]); return null; //返回参数值
        }
        //使用方法, url中包含id这个参数
        var uid = getUrlParam("uid")

        if ("WebSocket" in window)
        {
            console.log('接收到的user_id='+user_id);
            //创建webSocket对象
            //var ws = new WebSocket("wss://test.***********.cn/wss?user_id="+user_id);  //测试
            //连接建立时触发
            ws.onopen = function()
            {
                console.log('已经建立连接');
            }

            //客户端接收服务端数据时触发
            ws.onmessage = function (evt)
            {
                var received_msg = evt.data;
                console.log('收到推送的消息:'+received_msg);
            }

            //连接关闭时触发
            ws.onclose = function(evt)
            {
                console.log("连接已关闭...");
            }

            //连接关闭时触发
            ws.onerror = function()
            {
                console.log("连接发生错误...");
            }
        }

        else
        {
            // 浏览器不支持 WebSocket
            alert("您的浏览器不支持 WebSocket!");
        }

        function sendData() {
            var msg = $("#msg").val();
            ws.send(msg);
        }
    </script>

</head>
<body>

<input type="text" placeholder="请输入要发送的文字" id="msg">

<button onclick="send_Data()">点击发送</button>

</body>
</html>

5、配置supervisor

[program:websocket-job]
command=php yii queue/listen websocket-job
directory=/data/test.*********.cn/
autorestart=true
startsecs=3
startretries=3
stdout_logfile=log/websocket-job.out.log
stderr_logfile=log/websocket-job.err.log
stdout_logfile_maxbytes=2MB
stderr_logfile_maxbytes=2MB
user=111111
priority=999
numprocs=1
process_name=%(program_name)s_%(process_num)02d

猜你喜欢

转载自blog.csdn.net/hechenhongbo/article/details/125390009