php 子进程监听消息,swoole学习笔记之多线程端口监听问题记录 多进程epoll模式...

epoll模式 主要就是直接对socket进行监听,不需要轮询,如果socket有状态变化就会触发

class Worker{

//监听socket

protected $socket = NULL;

//连接事件回调

public $onConnect = NULL;

public  $reusePort=1;

//接收消息事件回调

public $onMessage = NULL;

public $workerNum=2; //子进程个数

public  $allSocket; //存放所有socket

public  $addr;

public function __construct($socket_address) {

//监听地址+端口

$this->addr=$socket_address;

}

public function start() {

//获取配置文件

$this->fork();

}

public function fork(){

for ($i=0;$iworkerNum;$i++){

$pid=pcntl_fork(); //创建成功会返回子进程id

if($pid<0){

exit("创建失败");

}else if($pid>0){

//父进程空间,返回子进程id

}else{ //返回为0子进程空间

echo "zi";

$this->accept();//子进程负责接收客户端请求

exit;//为什么这里exit退出后子进程不退出?这里应该时阻止继续运行,然后经常在监听,所以没有退出

}

}

exit;//这里如果exit,主进程就会退出来,导致下面结束子进程的代码失效

//放在父进程空间,结束的子进程信息,阻塞状态

$status=0;

for ($i=0;$iworkerNum;$i++) {

$pid = pcntl_wait($status);

}

}

public  function  accept(){

$opts = array(

"socket" => array(

"backlog" =>10240, //成功建立socket连接的等待个数

),

);

//创建资源流上下文

$context = stream_context_create($opts);

//开启多端口监听,并且实现负载均衡

//stream_context_set_option 设置资源流

// 参数 $stream_or_context, $wrapper, $option, $value

//$stream_or_context 资源流上下文

//$wrapper,包装器(wrapper),包括 http,socket,ssl等

//$option 设置的选项(不确定)

//$value 选项对应的值

//设置端口可以多个监听,开启监听端口复用后允许多个无亲缘关系的进程监听相同的端口,并且由系统内核做负载均衡,

//决定将socket连接交给哪个进程处理,避免了惊群效应,

//可以提升多进程短连接应用的性能。

stream_context_set_option($context,"socket","so_reuseport",1);

stream_context_set_option($context,"socket","so_reuseaddr",1);

$this->socket=stream_socket_server($this->addr,$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$context);

//第一个需要监听的事件(服务端socket的事件),一旦监听到可读事件之后会触发

//异步监听

swoole_event_add($this->socket,function ($fd){

$clientSocket=stream_socket_accept($fd);

//触发事件的连接的回调

if(!empty($clientSocket) && is_callable($this->onConnect)){

echo "连接事件触发",(int)$clientSocket,PHP_EOL;

call_user_func($this->onConnect,$clientSocket);

}

//监听客户端可读

swoole_event_add($clientSocket,function ($fd){

//从连接当中读取客户端的内容

$buffer=fread($fd,1024);

//如果数据为空,或者为false,不是资源类型

if(empty($buffer)){

if(!is_resource($fd) || feof($fd) ){

//触发关闭事件

fclose($fd);

}

}

//正常读取到数据,触发消息接收事件,响应内容

if(!empty($buffer) && is_callable($this->onMessage)){

call_user_func($this->onMessage,$fd,$buffer);

}

});

});

}

}

$worker = new Worker("tcp://0.0.0.0:9801");

//开启多进程的端口监听

$worker->reusePort = true;

//连接事件

$worker->onConnect = function ($fd) {

echo "连接事件触发",(int)$fd,PHP_EOL;

};

//消息接收

$worker->onMessage = function ($conn, $message) {

var_dump("123");

$content="123123123";

$http_resonse = "HTTP/1.1 200 OK

";

$http_resonse .= "Content-Type: text/html;charset=UTF-8

";

$http_resonse .= "Connection: keep-alive

"; //连接保持

$http_resonse .= "Server: php socket server

";

$http_resonse .= "Content-length: ".strlen($content)."

";

$http_resonse .= $content;

fwrite($conn, $http_resonse);

};

$worker->start(); //启动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值