swoole同时连接 tcp http WebSocket三端数据交互

服务器代码

<?php

use Swoole\WebSocket\Server;

class Test
{
    public $ws;
    public $redis;

    public function __construct()
    {

        Co::set(['enable_preemptive_scheduler' => 0]);
        $this->ws = new Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
        $Config = [
            'open_http_protocol' => true,
        ];
        $this->ws->set($Config);
        $this->ws->on('open', [$this, 'onOpen']);
        $this->ws->on('message', [$this, 'onMessage']);
        $this->ws->on('WorkerStart', [$this, 'onWorkerStart']);
        $this->ws->on('request', [$this, 'onRequest']);
        $this->ws->on('close', [$this, 'onClose']);

        $serv = $this->ws->addlistener('0.0.0.0', 9503, SWOOLE_SOCK_TCP);
        $serv->set([]);
        $serv->on('receive', [$this, 'onReceive']);
    }

    public function onWorkerStart()
    {
        $this->redis = new Swoole\Coroutine\Redis();
        $this->redis->connect('127.0.0.1', '6379');
        $this->redis->auth('123456');
        //清空绑定关系
        $this->redis->del('user_fd');
        $this->redis->del('device_user');
        $this->redis->del('device_fd');
    }


    /**打开webscokt连接
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        $ws->push($request->fd, "hello, welcome\n");

    }

    /**websockt收到数据回调
     * @param $ws
     * @param $frame
     * @return bool
     */
    public function onMessage($ws, $frame)
    {

        $data = json_decode($frame->data, true);
        $user_id = $data['user_id'] ?? null;
        $device_id = $data['device_id'] ?? null;
        if (!$user_id || !$device_id) {
            $this->ws->push($frame->fd, "Parameter error");
            return false;
        }
        $this->redis->hset('user_fd', $user_id, $frame->fd);
        $this->redis->hset('device_user', $device_id, $user_id);
        $this->ws->push($frame->fd, "server: {$frame->data}");
    }

    public function onClose($ws, $fd)
    {
        echo "client-{$fd} is closed\n";

    }

    /**http请求回调
     * @param $request
     * @param $response
     */
    public function onRequest($request, $response)
    {
        $post_data = $request->post;
        $device_cmd = $post_data['cmd'] ?? null;
        $device_id = $post_data['device_id'] ?? null;
        $device_fd = $this->redis->hget('device_fd', $device_id);

        $user_id = $this->redis->hget('device_user', $device_id);
        $user_fd = $this->redis->hget('user_fd', $user_id);
        if ($user_fd) $this->ws->push($user_fd, $device_cmd);

        //发送数据到tcp服务
        if ($device_fd) {
            $client = new \Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
            $client->set(['max_coroutine' => 5,]);
            if (!$client->connect('127.0.0.1', 9503, 0.5)) {
                exit("connect failed. Error: {$client->errCode}\n");
            }
            $str = json_encode(['device_fd' => $device_fd, 'device_cmd' => $device_cmd]);
            $client->send($str . "\r\n");
//        echo $client->recv();
            $client->close();
        }
        $response->header("Content-Type", "text/html; charset=utf-8");
        $response->end("<h1>OK. #" . rand(1000, 9999) . "</h1>");
    }


    /**tcp接收数据回调
     * @param $serv
     * @param $fd
     * @param $threadId
     * @param $data
     */
    public function onReceive($serv, $fd, $threadId, $data)
    {
        $data = json_decode($data, true);
        $device_id = $data['device_id'] ?? null;
        $device_fd = $data['device_fd'] ?? null;
        $device_cmd = $data['device_cmd'] ?? null;
        //绑定设备关系
        if ($device_id) $this->redis->hset('device_fd', $device_id, $fd);
        //发送到设备数据
        if ($device_fd) $serv->send($device_fd, $device_cmd);

    }

    public function start()
    {
        $this->ws->start();
    }
}

$model = new Test();
$model->start();

web前端代码

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>测试</title>
    
      <script type="text/javascript">
       
    
               
               // 打开一个 web socket
               var ws = new WebSocket("ws://127.0.0.1:9501");
                
               ws.onopen = function()
               {
                var str='{"user_id":1,"device_id":1}';
                    ws.send(str);
                      console.log('已链接');
               };
                
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                 console.log(evt.data);
               };
                
               ws.onclose = function()
               { 
                  // 关闭 websocket
                    console.log('已关闭');
               };
          
      </script>
        
   </head>
   <body>
      
   </body>
</html>

测试,我们用tcp与WebSocket分别连接上服务器,然后通过http发送数据,然后在tcp与WebSocket都能收到数据
postman发送数据


13034051-504f40781c375316.png
image.png

tcp端


13034051-4912a90644e7c15c.png
image.png

WebSocket端


13034051-9531d8d88203ddb2.png
image.png
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值