swoolel代码演示 - IO模式之非阻塞模式

先来看看服务器的代码,这次先封装一下

namespace Zhcsam\Io\Nonblocking;
class Worker
{

    // 自定义服务的事件注册函数,
    // 这三个是闭包函数
    public $onReceive = null;
    public $onConnect = null;
    public $onClose = null;

    // 连接
    public $socket = null;

    public function __construct($socket_address)
    {
        $this->socket = stream_socket_server($socket_address);
        // echo $socket_address."\n";
        // $this->debug('stream_socket_server($socket_address);');
        // $this->debug($this->socket, true);
    }
    // 需要处理事情
    public function accept()
    {
        // 接收连接和处理使用
        while (true) {
            $this->debug("accept start");

            // 监听的过程是阻塞的
            $client = stream_socket_accept($this->socket);

            // is_callable判断一个参数是不是闭包
            if (is_callable($this->onConnect)) {
                // 执行函数
                ($this->onConnect)($this, $client);
            }
            // tcp 处理 大数据 重复多发几次
            // $buffer = "";
            // while (!feof($client)) {
            //    $buffer = $buffer.fread($client, 65535);
            // }

            $data = fread($client, 65535);
            if (is_callable($this->onReceive)) {
                ($this->onReceive)($this, $client, $data);
            }
            $this->debug("accept end");
            // 处理完成之后关闭连接
            // 心跳检测 - 自己的心跳
            // fclose($client);
        }
    }
    public function debug($data, $flag = false)
    {
        if ($flag) {
            var_dump($data);
        } else {
            echo "==== >>>> : ".$data." \n";
        }
    }
    // 发送信息
    public function send($client, $data)
    {
        $response = "HTTP/1.1 200 OK\r\n";
        $response .= "Content-Type: text/html;charset=UTF-8\r\n";
        $response .= "Connection: keep-alive\r\n";
        $response .= "Content-length: ".strlen($data)."\r\n\r\n";
        $response .= $data;
        echo '发送信息中。。。。';
        fwrite($client, $response);
    }


    // 启动服务的
    public function start()
    {
        $this->accept();
    }
}

再来生成服务器实例,代码如下 

此函数的闭包函数赋值给主类的成员

<?php
require __DIR__.'/../../vendor/autoload.php’;
use Zhcsam\Io\NonBlocking\Worker;
$host = "tcp://0.0.0.0:9000";
$server = new Worker($host);
$server->onConnect = function($socket, $client){
    echo "有一个连接进来了\n";
};

// 接收和处理信息
$server->onReceive = function($socket, $client, $data){

    echo "给连接发送信息2222\n";
    sleep(3);
    $socket->send($client, "hello world cli8888ent \n");
    // fwrite($client, "server hellow");
};
$server->start();

然后再来看看客户端的代码

<?php
$host ="tcp://0.0.0.0:9000";
$cliect = stream_socket_client($host);
stream_set_blocking($cliect, 0);
$new =time();
echo "客户端连接中\n";
fwrite($cliect,'客户端发来信息');
echo "其它业务\n";
echo "用时".(time()-$new)."\n";

while (!feof($cliect)) {
   echo "轮询中……\n";
   var_dump(fread($cliect, 65535));
   sleep(1);
}

客户端用stream_set_blocking设置非阻塞,服务端也是可以设置

在命令行运行服务端

php server.php 
==== >>>> : accept start 

(此时正在等待客户端连接)


命令行运行客户端 

php client.php 

客户端连接中
其它业务
用时0
轮询中……
string(0) ""
轮询中……
string(0) ""
轮询中……
string(0) ""
轮询中……
string(126) "HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Content-length: 24

hello world cli8888ent 
"

string(0) ""
轮询中……
string(0) ""
轮询中……
string(0) ""

一直重复执行


服务端的界面如下:

==== >>>> : accept start 
有一个连接进来了
给连接发送信息2222
发送信息中。。。。==== >>>> : accept end 
==== >>>> : accept start 

(服务器重新监听是否有下一次新的连接)


从客户端的界面可以观察到:

  • 用时为0,但数据并没有马上返回
  • 需要轮询,几秒后服务器才返回,打印出带“hello world cli8888ent ”等文字

非阻塞的模式后面也是不断要轮询,较消耗资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值