php多进程socket,php实现多进程socket服务器class

该类实现了多进程的socket服务,目前只写了关于TCP协议,待完善其他内容

所需扩展:socket  pcntl<?php

/**

* Created by PhpStorm.

* User: tioncico

* Date: 18-5-1

* Time: 下午7:56

*/

class SphpSocket

{

private static $_instance;

public $connect_list = array();//客户端列表

public $connect_callback, $receive_callback, $close_callback;//回调函数

public $server;//socket服务

public $is_run=true;//是否运行

public $config = array(//各种配置

'debug'=>true,

'host' => '0.0.0.0',

'port' => '9501',

'domain'   => AF_INET,

'type'     => SOCK_STREAM,

'protocol' => SOL_TCP,

'accept' => 511,

'option_level' => SOL_SOCKET,

'optname'      => SO_REUSEADDR,

'optval'       => 1,

'read_length'=>1024,

'read_type'=>PHP_NORMAL_READ

);

public $error_log=array();

public static function getInstance($host, $port)

{

if (!(self::$_instance instanceof self)) {

self::$_instance = new static($host, $port);

}

return self::$_instance;

}

public function __construct($host, $port)

{

$this->config['host'] = $host;

$this->config['port'] = $port;

}

/**

* 绑定事件

* @param $type connect|receive|close

* @param callable $function

*/

public function on($type, callable $function)

{

switch (strtolower($type)) {

case 'connect':

$this->connect_callback = $function;

break;

case 'receive':

$this->receive_callback = $function;

break;

case 'close':

$this->close_callback = $function;

break;

}

return $this;

}

public function onConnect($connection){

if (is_callable($this->connect_callback)) {

call_user_func($this->connect_callback,$connection);

}

}

public function onReceive($connection,$data){

if (is_callable($this->receive_callback)) {

call_user_func($this->receive_callback,$connection,$data);

}

}

public function onClose($connection){

if (is_callable($this->close_callback)) {

call_user_func($this->close_callback,$connection);

}

}

/**

*

*/

public function start()

{

$this->createSocket();

echo '创建socket成功!'.PHP_EOL;

$this->bindSocket();

echo '绑定端口成功!'.PHP_EOL;

$this->listenSocket();

echo '监听端口成功!'.PHP_EOL;

$this->setOptionSocket();

$this->acceptSocket();

return $this;

}

/**

* 创建socket

* @return $this

* @throws Exception

*/

protected function createSocket()

{

$this->server = socket_create($this->config['domain'], $this->config['type'], $this->config['protocol']);

if ($this->server === false) {

throw new Exception('创建socket失败!');

}

return $this;

}

/**

* 绑定端口

* @return $this

* @throws Exception

*/

protected function bindSocket()

{

$this->server === false && $this->createSocket();

$result = socket_bind($this->server, $this->config['host'], $this->config['port']);

if ($result === false) {

throw new Exception('绑定端口失败!');

}

return $this;

}

/**

* 监听端口

* @param null $accept

* @return $this

* @throws Exception

*/

protected function listenSocket($accept = null)

{

$this->server === false && $this->createSocket();

$accept || $accept = $this->config['accept'];

$result = socket_listen($this->server, $accept);

if ($result === false) {

throw new Exception('监听端口失败!');

}

return $this;

}

/**

* 配置socket

* @return $this

* @throws Exception

*/

protected function setOptionSocket()

{

$this->server === false && $this->createSocket();

$result = socket_set_option($this->server, $this->config['option_level'], $this->config['optname'], $this->config['optval']);

if ($result === false) {

throw new Exception('配置socket失败!');

}

return $this;

}

/**

* 接收socket连接

*/

protected function acceptSocket(){

$this->server === false && $this->createSocket();

while(true&&$this->is_run===true){

$connection = socket_accept($this->server);

if($connection===false){

}else{

$this->addConnectionList($connection);

$this->onConnect($connection);

$this->forkProcess($connection);

}

}

}

/**

* 写入客户端信息

* @param $connection

* @return $this

*/

protected function addConnectionList($connection){

//        $fd =

$this->connect_list[(string)$connection]['fd']=$connection;

return $this;

}

/**

* 写入客户端进程id

* @param $connection

* @param $pid

* @return $this

*/

protected function addConnectionListProcess($connection,$pid){

$this->connect_list[(string)$connection]['pid']=$pid;

return $this;

}

/**

* 派生进程处理

* @param $connection

*/

protected function forkProcess($connection){

$pid = pcntl_fork();

if($pid>0){//使用主进程处理客户端其他请求,子进程继续监听连接请求

$this->addConnectionListProcess($connection,$pid);

$this->readSocket($connection);

}else{

}

}

/**

* 读取socket信息

* @param $connection

*/

protected function readSocket($connection){

while(true&&isset($this->connect_list[(string)$connection])&&$this->is_run){

$data = @socket_read($connection,$this->config['read_length'],$this->config['read_type']);

if($data===false){

$this->close($connection);

}else{

$this->onReceive($connection,$data);

}

}

}

/**

* 发送消息给客户端

* @param $connection

* @param $msg

* @return int

*/

public function send($connection,$msg){

$result = socket_write($connection, $msg,strlen($msg));

return $result;

}

/**

* 主动关闭客户端

* @param $connection

*/

public function close($connection){

$this->onClose($connection);

//先关掉子进程

posix_kill($this->connect_list[(string)$connection]['pid'],SIGTERM);

$result = socket_close($connection);

unset($this->connect_list[(string)$connection]);

return $result;

}

}

开启例子:$socket = SphpSocket::getInstance('0.0.0.0',9501);

$socket->on('connect',function ($connection)use($socket){

$socket->send($connection,'恭喜您连接成功!');

});

$socket->on('receive',function ($connection,$data)use($socket){

$result = $socket->send($connection,'您发送的消息是:'.$data);

var_dump($data);

if(trim($data)=='关闭'){

$socket->close($connection);

}

echo "发送消息成功";

});

$socket->on('close',function ($connection)use($socket){

var_dump($connection.'已经关闭连接');

});

$socket->start();

8447bef9fab1cf81416907758e210c95.png

本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值