page contents

swoole 第6次课-2 含毫命简:阻塞与非阻塞

阻塞与非阻塞

1.回顾阻塞模型

11)手写网络模型,实现的目录结构

   attachments-2020-11-tygjyi7R5fc432927db30.png

12)当前目录网络结构

  attachments-2020-12-Xv7YoF285fd975f37ed49.jpg

根据以上,建立对应文件

13)六个用到的函数

 attachments-2020-12-WJO6CG1m5fc59d7beee25.png

实质,服务端与客户端,是通过 stream_socket_accept连接的,即stream_socket_client---->stream_socket_accept--->stream_socket_server

14)回顾阻塞模型

attachments-2020-11-VU96Vl9u5fc2e21dbdf93.png

客户请求服务获取信息的本质过程,对于服务来说:

(1). 连接  ( 2). 响应请求(就是执行相应的代码)

2构建基础 worker结构(工程结构)

21)补充:上节服务端即 iostarjhy\test\swoole\tcpserver2.php中,为什么要while循环?我们改成如下
<?php
//建立协议服务
$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
//创建服务和客户和客户连接的socket stream_socket_accept
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
//while 循环,可多次连接
/*while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);*/

//while改成以下,无法做到多次连接
$conn = stream_socket_accept($socket);
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);

//网络上的通常做法,while(ture)
/* while(true){ //始终监测 是否有信息发过来
$conn = stream_socket_accept($socket);
var_dump(fread($conn,65535));
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}*/
}
        客户端:iostarjhy\test\swoole\clinet2.php同上节,如下
<?php
//连接服务端
$client = new Swoole\Client(SWOOLE_SOCK_TCP );

if (!$client->connect('127.0.0.1', 8000, -1)) {
exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");
/*$client->send("hello world\n");
$client->send("hello world\n");
$client->send("hello world\n");*/

echo $client->recv();

$client->close();
运行如下
attachments-2020-12-szk26Dz95fd9c6e2138d3.png

可见,$conn = stream_socket_accept($socket);可连接一次,服务端就关闭了,再次运行客户端,提示说服务端关闭了。
通常,网络上还有while(true)的做法(见iostarjhy\test\swoole\tcpserver2.php中最下面注释),就是实现多次连接,切换注释,运行结果如下:
attachments-2020-12-6qWstSKk5fd9c7a60f099.jpg

22)思路分析

221)基于客户请求服务获取信息的本质过程,服务具备的功能及方法

attachments-2020-12-EUX4067I5fd97a701a4b1.jpg

222)构建基础服务结构,基础类workbase,实现的基本功能
attachments-2020-12-YPQo8sw15fd97c90cadc3.png
整个IoStar,基于这个workBase,最终结构如下:

attachments-2020-12-MUYRemo65fd97cbdc2bad.png

23)创建基类 iostarjhy\src\WorkerBase.php

<?php
namespace IoStarJhy;

abstract class WorkerBase
{
protected $server;
protected $events=[];
protected $config;
protected $typc="tcp";

public function __construct($host,$port){
$this->server = stream_socket_server("tcp://".$host.":".$port);
echo "tcp://".$host.":".$port."\n";
}
/**
* 不同的模型实现不一样
* @var [type]
*/
protected abstract function accept();
/**
* 添加事件
* @method on
* @param [type] $event [description]
* @param [type] $call [description]
* @return [type] [description]
*/
public function on($event,$call){
$this->events[strtolower($event)] = $call;
}

public function set(){}

/**
* 发送信息
* @method send
* @param [type] $client [description]
* @param [type] $data [description]
* @return [type] [description]
*/
public function send($client,$data)
{

}

public function start()
{
var_dump($this->events);
$this->accept();
}

public function close()
{

}


}
 iostarjhy\src\Blocking\Worker.php
<?php
namespace IoStarJhy\Blocking;

use IoStarJhy\WorkerBase;

class Worker extends WorkerBase {

public function accept()
{

}
}
测试iostarjhy\test\Blocking\server.php
<?php
require_once __DIR__."/../../vendor/autoload.php";

use IoStarJhy\Blocking\Worker;

$server = new Worker('0.0.0.0',9500);

$server->on('connect',function($server,$client){

});
$server->on('receive',function($server,$client,$data){

});
$server->on('close',function($server,$client){

});

$server->start();
运行,可以看到各事件已注册了
attachments-2020-12-4DrjEtpd5fd9e1ee577e5.png


24)为方便测试,增加个调试的助手函数 dd($message, $description)
241)iostarjhy\src\Support\Helper.php  
<?php

function dd($message, $description = null)
{
echo "======>>> ".$description." start\n";
if (\is_array($message)) {
echo \var_export($message, true);
} else if (\is_string($message)) {
echo $message."\n";
} else {
var_dump($message);
}
echo "======>>> ".$description." end\n";
}
242)修改 iostarjhy\composer.json  就是在autoload的属性对象中增加 files属性,指示助手函数地址
{
"name": "jhy/iostarjhy",
"type": "library",
"authors": [
{
"name": "jhy",
"email": "1195863294@qq.com"
}
],
"autoload": {
"psr-4": {
"IoStarJhy\\": "src"
},
"files":[
"src/Support/Helper.php"
]
},
"require": {}
}

243)命令更新,但最好用 composer dumpautoload

D:\phpstudy_pro\WWW\swoole_2006\iostarjhy>composer update

244)上传代码到服务器

245)使用测试

iostarjhy\src\WorkerBase.php的 __construct()及start()方法,改造如下:

public function __construct($host,$port){

$this->server = stream_socket_server("tcp://".$host.":".$port);
//echo "tcp://".$host.":".$port."\n";
dd("tcp://".swoole_get_local_ip()['ens33'].":".$port,"创建手写的worker服务");
}
public function start()
{
//var_dump($this->events);
dd($this->events,"启动后,输出服务的注册事件");
$this->accept();
}

运行

attachments-2020-12-08Pn4RlW5fd9f6094fb16.png


未完,见swoole 第6次课-2 含毫命简:阻塞与非阻塞2

六星社区-程序员编程技术分享交流学习高端论坛

  • 发表于 2020-12-15 10:37
  • 阅读 ( 922 )
  • 分类:swoole

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
吉洪叶
吉洪叶

21 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1658 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章