当前位置: 首页 > 工具软件 > PHP WebSocket > 使用案例 >

php websocket远程调用curl查询数据库

高砚
2023-12-01
<!DOCTYPE html>
<html>
<head>
    <title>简易聊天Demo</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
    <link href="https://cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        <!--
        html, body {
            min-height: 100%;
        }

        body {
            margin: 0;
            padding: 0;
            width: 100%;
            font-family: "Microsoft Yahei", sans-serif, Arial;
        }

        .container {
            text-align: center;
        }

        .title {
            font-size: 16px;
            color: rgba(0, 0, 0, 0.3);
            position: fixed;
            line-height: 30px;
            height: 30px;
            left: 0px;
            right: 0px;
            background-color: white;
        }

        .content {
            background-color: #f1f1f1;
            border-top-left-radius: 6px;
            border-top-right-radius: 6px;
            margin-top: 30px;
        }

        .content .show-area {
            text-align: left;
            padding-top: 8px;
            padding-bottom: 168px;
        }

        .content .show-area .message {
            width: 70%;
            padding: 5px;
            word-wrap: break-word;
            word-break: normal;
        }

        .content .write-area {
            position: fixed;
            bottom: 0px;
            right: 0px;
            left: 0px;
            background-color: #f1f1f1;
            z-index: 10;
            width: 100%;
            height: 160px;
            border-top: 1px solid #d8d8d8;
        }

        .content .write-area .send {
            position: relative;
            top: -28px;
            height: 28px;
            border-top-left-radius: 55px;
            border-top-right-radius: 55px;
        }

        .content .write-area #name {
            position: relative;
            top: -20px;
            line-height: 28px;
            font-size: 13px;
        }

        -->
    </style>
</head>
<body>
<div class="container">
    <div class="title">简易聊天demo</div>
    <div class="content">
        <div class="show-area"></div>
        <div class="write-area">
            <div>
                <button class="btn btn-default send">发送</button>
            </div>
            <div><input name="name" id="name" type="text" placeholder="input your name"></div>
            <div>
                <textarea name="message" id="message" cols="38" rows="4" placeholder="input your message..."></textarea>
            </div>
        </div>
    </div>
</div>
<!-- <#--弹窗-->
<!-- <div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h4 class="modal-title" id="myModalLabel">
                    提醒
                </h4>
            </div>
            <div class="modal-body" id="modealContent">
                你有新的订单
            </div>
            <div class="modal-footer">
                <button onclick="stopAudio()" type="button"
                        class="btn  btn-info" data-dismiss="modal">关闭
                </button>
                <button onclick="location.reload()" type="button" class="btn btn-primary">查看订单</button>
            </div>
        </div>
    </div>
</div>


<#--播放下单音乐-->
<!--<audio id="notice" loop="loop">
    <source src="/diancan/mp3/laidanle.wav" type="audio/mpeg"/>
</audio>
<#--播放催单音乐-->
<!--<audio id="notice2" loop="loop">
    <source src="/diancan/mp3/cuidan.wav" type="audio/mpeg"/>
</audio> --> 

<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script>
    $(function () {
        var wsurl = 'ws://www.xxxx.com:9999/server.php';
        var websocket;
        var i = 0;
        if (window.WebSocket) {
            websocket = new WebSocket(wsurl);

            //连接建立
            websocket.onopen = function (evevt) {
                console.log("Connected to WebSocket server.");
                $('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>Connected to WebSocket server!</p>');
             websocket.send("1231");
            }
         
            //收到消息
            websocket.onmessage = function (event) {
                var msg = JSON.parse(event.data); //解析收到的json消息数据

                var type = msg.type; // 消息类型
                var umsg = msg.message; //消息文本
                var uname = msg.name; //发送人
                i++;
                if (type == 'usermsg') {
                    $('.show-area').append('<p class="bg-success message"><i class="glyphicon glyphicon-user"></i><a name="' + i + '"></a><span class="label label-primary">' + uname + ' : </span>' + umsg + '</p>');
                }
                if (type == 'system') {
                    $('.show-area').append('<p class="bg-warning message"><a name="' + i + '"></a><i class="glyphicon glyphicon-info-sign"></i>' + umsg + '</p>');
                }

                $('#message').val('');
                window.location.hash = '#' + i;
            }

            //发生错误
            websocket.onerror = function (event) {
                i++;
                console.log("Connected to WebSocket server error");
                $('.show-area').append('<p class="bg-danger message"><a name="' + i + '"></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>');
                window.location.hash = '#' + i;
            }

            //连接关闭
            websocket.onclose = function (event) {
                i++;
                console.log('websocket Connection Closed. ');
                $('.show-area').append('<p class="bg-warning message"><a name="' + i + '"></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>');
                window.location.hash = '#' + i;
            }

          /*  function send() {
                var name = $('#name').val();
                var message = $('#message').val();
                if (!name) {
                    alert('请输入用户名!');
                    return false;
                }
                if (!message) {
                    alert('发送消息不能为空!');
                    return false;
                }
                var msg = {
                    message: message,
                    name: name
                };
                try {
                    websocket.send(JSON.stringify(msg));
                } catch (ex) {
                    console.log(ex);
                }
            } */
 
            //按下enter键发送消息
            /* $(window).keydown(function (event) {
                if (event.keyCode == 13) {
                    console.log('user enter');
                    send();
                }
            });

            //点发送按钮发送消息
            $('.send').bind('click', function () {
                send();
            }); 
 */
        }
        else {
            alert('该浏览器不支持web socket');
        }

    });
</script>



<!-- <script type="text/javascript">
    //停止播放音乐
    function stopAudio() {
        document.getElementById('notice').pause()
        document.getElementById('notice2').pause()
    }


    var websocket = null;
    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://127.0.0.1:12345/server.php");
    } else {
        alert('Not support websocket')
    }
    //连接发生错误的回调方法
    websocket.onerror = function () {
        alert('websocket通信发生错误!');
    };

    //连接成功建立的回调方法
    websocket.onopen = function (event) {
        console.log('建立连接');
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        let msg = event.data
        console.log('收到消息:' + msg)
        //弹窗提醒, 播放音乐
        $('#myModal').modal('show');

        if (msg == 0) {
            document.getElementById('notice').play();//下单音频
        } else {
            $('#modealContent').html(msg + "的顾客催单了,请赶快上餐")
            document.getElementById('notice2').play();//催单音频
        }
    }

    //连接关闭的回调方法
    websocket.onclose = function () {
        console.log("websocket链接关闭")
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        websocket.close();
    }
</script> -->

</body>
</html>

2.创建接口文件

<?php
pc_base::load_sys_class('model', '', 0);
//echo "进入打印接口";

//进行数据库操作
class download extends model
{
    function __construct()
    {
        parent::__construct();
        $this->db_config = pc_base::load_config('database');
        $this->db_setting = 'default';
        $this->table_name = 'v9_download';
    }
}
    //接口里面需要创建对象
    $download_db = new download();
    $data_down = $download_db->select("","id,url","1","id desc");

          foreach((array)$data_down as $key=> $item){
              if($item['id']>425) {
                  echo $key . "--单表查询--" . $item['url'] . $item['id'] . "<br>";
              }

      }

?>

3.创建服务websocket服务

<?php
/*//1.初始化curl,返回资源
$curl = curl_init();
//2.设置curl请求的服务器文件地址
//CURLOPT_RETURNTRANSFER将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);//设置将结果返回而不是直接输出
//针对https协议的请求,需要验证客户端的安全证书,通常都会跳过安全证书的验证
//跳过百度的https验证证书
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($curl,CURLOPT_URL,"https://www.baidu.com/index.php");//CURLOPT_URL需要获取的URL地址,也可以在curl_init()函数中设置。
//CURLOPT_HEADER是否返回header头信息
curl_setopt($curl,CURLOPT_HEADER,0);//不返回header头信息
//3.发出请求,接受返回的数据
$result = curl_exec($curl);
echo '<pre>';
var_dump($result);
//4.关闭资源
curl_close($curl);*/
//利用curl调用外部接口,查看数据库数据是否有更新,如果有更新,则打印出来
// 1.初始化curl,返回资源
$ch = curl_init();
//2. 不管是get、post,跳过证书的验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
//3.设置请求的服务器地址
curl_setopt($ch, CURLOPT_URL, "http://www.tuibeitu.1xz.cn/api.php?op=print_api");
//4.设置将结果返回而不是直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
var_dump($result);
echo "进来了";
$host = '0.0.0.0';
$port = '9999';
$null = NULL;

//创建tcp socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);//重用端口1表示接受所有的数据包
socket_bind($socket, 0, $port);//把socket绑定在一个IP地址和端口上

//监听端口
socket_listen($socket);

//连接的client socket 列表
$clients = array($socket);

//设置一个死循环,用来监听连接 ,状态//死循环,直到socket断开
while (true) {

    $changed = $clients;
    /*
        //这个函数是同时接受多个连接的关键,我的理解它是为了阻塞程序继续往下执行。
        socket_select ($sockets, $write = NULL, $except = NULL, NULL);
 
        $sockets可以理解为一个数组,这个数组中存放的是文件描述符。当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。
        $write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。
        $except是$sockets里面要被排除的元素,传入NULL是”监听”全部。
        最后一个参数是超时时间
        如果为0:则立即结束
        如果为n>1: 则最多在n秒后结束,如遇某一个连接有新动态,则提前返回
        如果为null:如遇某一个连接有新动态,则返回
        */
    socket_select($changed, $null, $null, 0, 10);

    //如果有新的连接
    if (in_array($socket, $changed)) {
        //接受并加入新的socket连接
        $socket_new = socket_accept($socket);//接受一个socket连接
        $clients[] = $socket_new;//将新连接进来的socket存进连接池

        //通过socket获取数据执行handshake
       
        $header = socket_read($socket_new, 1024);
        perform_handshaking($header, $socket_new, $host, $port);

        //获取client ip 编码json数据,并发送通知
        socket_getpeername($socket_new, $ip);
        $response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' connected')));
        send_message($response);
        $found_socket = array_search($socket, $changed);
        unset($changed[$found_socket]);
    }

    //轮询 每个client socket 连接
    foreach ($changed as $changed_socket) {

        //如果有client数据发送过来
        /* while (socket_recv($changed_socket, $buf, 1024, 0) >= 1) {
            //解码发送过来的数据
            $received_text = unmask($buf);
            $tst_msg = json_decode($received_text);
            $user_name = $tst_msg->name;
            $user_message = $tst_msg->message;

            //把消息发送回所有连接的 client 上去
            //$response_text = mask(json_encode(array('type' => 'usermsg', 'name' => "$user_name", 'message' => $user_message)));
         $response_text = mask(json_encode(array('type' => 'usermsg', 'name' => "服务器端", 'message' => "我是从服务器过来啦")));
            send_message($response_text);
            break 2;
        } */
        while (1==1) {
            // 1.初始化curl,返回资源
            $ch = curl_init();
            //2. 不管是get、post,跳过证书的验证
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            //3.设置请求的服务器地址
            curl_setopt($ch, CURLOPT_URL, "http://www.tuibeitu.1xz.cn/api.php?op=print_api");
            //4.设置将结果返回而不是直接输出
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $result = curl_exec($ch);
            curl_close($ch);
            var_dump($result);
            echo "进来了";

        //把消息发送回所有连接的 client 上去
        $response_text = mask(json_encode(array('type' => 'usermsg', 'name' => "服务器端", 'message' =>  $result)));
        send_message($response_text);
        }
      //如果有client数据发送过来
      /*for($x=1;$x<=50;$x++) {
          //解码发送过来的数据
          $received_text = unmask($buf);
          $tst_msg = json_decode($received_text);
          $user_name = $tst_msg->name;
          $user_message = $tst_msg->message;
      
          //把消息发送回所有连接的 client 上去
          //$response_text = mask(json_encode(array('type' => 'usermsg', 'name' => "$user_name", 'message' => $user_message)));
         $response_text = mask(json_encode(array('type' => 'usermsg', 'name' => "服务器端", 'message' => "我是从服务器过来啦")));
          send_message($response_text);
          //break 2;
      } */

        //检查offline的client
        $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
        if ($buf === false) {
            $found_socket = array_search($changed_socket, $clients);
            socket_getpeername($changed_socket, $ip);
            unset($clients[$found_socket]);
            $response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' disconnected')));
            send_message($response);
        }
    }
}
// 关闭监听的socket
socket_close($sock);

//发送消息的方法
function send_message($msg)
{
    global $clients;
    foreach ($clients as $changed_socket) {
        @socket_write($changed_socket, $msg, strlen($msg));
    }
    return true;
}


//解码数据
function unmask($text)
{
    $length = ord($text[1]) & 127;
    if ($length == 126) {
        $masks = substr($text, 4, 4);
        $data = substr($text, 8);
    } elseif ($length == 127) {
        $masks = substr($text, 10, 4);
        $data = substr($text, 14);
    } else {
        $masks = substr($text, 2, 4);
        $data = substr($text, 6);
    }
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }
    return $text;
}

//编码数据
function mask($text)
{
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if ($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif ($length > 125 && $length < 65536)
        $header = pack('CCn', $b1, 126, $length);
    elseif ($length >= 65536)
        $header = pack('CCNN', $b1, 127, $length);
    return $header . $text;
}

//握手的逻辑
function perform_handshaking($receved_header, $client_conn, $host, $port)
{
    $headers = array();
    $lines = preg_split("/\r\n/", $receved_header);
    foreach ($lines as $line) {
        $line = chop($line);
        if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
            $headers[$matches[1]] = $matches[2];
        }
    }

    $secKey = $headers['Sec-WebSocket-Key'];
    $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
    $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
        "Upgrade: websocket\r\n" .
        "Connection: Upgrade\r\n" .
        "WebSocket-Origin: $host\r\n" .
        "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n" .
        "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
    socket_write($client_conn, $upgrade, strlen($upgrade));
}PhpStudy开发工具
 类似资料: