socket + pcntl_fork 实现客户端请求,服务器实时监听返回处理 消息推送

<?php
    /*
        socket链接整个过程
        1,socket_create
        第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET;
        第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部);
        第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。
        2,socket_connect
        3,socket_write
        4,socket_read
        5,socket_close
    */
    Class Client {
        static private $socket = null;

        public function __construct() {
            //不报错
            error_reporting(0);
            //引入数据库
            require_once(‘conn.php‘);
            if(self::$socket == null)
                self::$socket = socket_create(AF_INET,SOCK_STREAM,0);
            if(self::$socket === false)
                exit(‘create socket fail! please check it!‘ . $this->err());
        }

        //连接并发送数据
        public function conn($ip,$port,$data) {
            //数组数据序列号保存发送
            $data = serialize($data);
            if(!socket_connect(self::$socket,$ip,$port))
                exit(‘socket connect error!‘ . $this->err());
            if(socket_write(self::$socket,$data) === false)
                exit(‘socket write error!‘ . $this->err());
        }

        //获取数据
        public function getBack() {
            $res = socket_read(self::$socket,4096);
            if($res === false)
                exit(‘socket read error !‘ . $this->err());
            if($res)
                return $res;
            else
                return ‘nothing return‘;
        }

        //析构释放资源
        public function __destruct() {
            socket_close(self::$socket);
        }

        //错误
        private function err() {
            return socket_strerror(socket_last_error());
        }
    }

 

 

<?php
    /*
        socket 服务器通信整个过程
        socket_creat
        socket_bind
        socket_listen
        socket_accetp
        socket_read
        socket_write
        socket_close

        注:1,服务器需要开启php 的pcntl系列扩展,
            2,服务器必须开通对应端口,而且需跟客户端请求端口一致
    */
    //监听客户端触发,
    class Message {
        private $socket     = null;

        public function __construct($info) {
            $this->init($info);
            //子程序结束后,系统自动回收,避免产生僵尸进程
            pcntl_signal(SIGCLD, SIG_IGN);
            pcntl_signal(SIGCHLD,SIG_IGN);
            //dojob
            $this->doJob();
        }

        //初始化
        private function init($info) {
            //创建通信
            if(!$this->socket = socket_create(AF_INET,SOCK_STREAM,0))
                exit(‘error: create fail!‘ . $this->err());
            //绑定端口
            if(!socket_bind($this->socket,$info[‘ip‘],$info[‘port‘]))
                exit(‘error: bind fail‘ . $this->err());
            //监听端口
            if(!socket_listen($this->socket))
                exit(‘error: listen fail‘ . $this->err());
        }

        //处理数据
        public function doJob() {
            do{
                //接受一个通信
                $mes_sock     = socket_accept($this->socket);
                if($mes_sock === false)
                    exit(‘error: accept fail!‘ . $this->err());

                //读取到客户端传送过来的数据
                $mes_client = socket_read($mes_sock,4096);
                if($mes_client === false)
                    exit(‘error: read fail‘ . $this->err());
                $data         = unserialize($mes_client);

                //开始分进程
                $pid         = pcntl_fork();
                if($pid) {

                    //父进程
                    $remeg             = ‘‘;
                    if($data[‘type‘] == 1)
                        $remeg         = ‘request ok!‘;
                    else
                        $remeg         = ‘allow ok!‘;

                    //将消息返回
                    if(socket_write($mes_sock,$remeg) === false)
                        exit(‘error: write fail‘ . $this->err());
                }else {
                    require_once(‘Db.class.php‘);
                    $conn             = Db::getInstance(array(‘ip‘=>‘192.168.1.11‘,‘user‘=>‘root‘,‘pass‘=>‘123456‘,‘database‘=>‘test‘));
                    //子进程
                    if($data[‘type‘] == 1) {
                        //处理用户申请加入圈子,当消息发送成功后,更改数据库信息
                        echo "处理用户申请加入圈子\n";
                        //$sql ="UPDATE test_add SET status = 1 WHERE status  ";
                        die;
                    }else{
                        //处理圈主审核
                        echo "处理圈主审核\n";
                        die;
                    }
                }

                //释放资源
                socket_close($mes_sock);
            }while(1);
        }

        //错误
        private function err() {
            return socket_strerror(socket_last_error());
        }

        //析构释放
        public function __desctruct() {
            socket_close($this->socket);
        }
    }

    //运行
    $message     = new Message(array(‘ip‘=>‘192.168.1.6‘,‘port‘=>‘1935‘));

 

//附属的db类

<?php
    /*
        数据库类
    */
    class Db {
        //用于存放实例化的对象
        static private $_instance = null;

        //公共静态方法获取实例化的对象
        static protected function getInstance($data) {
            if (!(self::$_instance instanceof self)) {
                self::$_instance = new self($data);
            }
            return self::$_instance;
        }

        //私有克隆
        private function __clone() {}

        //私有构造
        private function __construct($data) {
            $conn             = mysql_connect($data[‘ip‘],$data[‘user‘],$data[‘pass‘]);
            if(!$conn)
                exit(‘数据库连接错误!‘ . mysql_error());
            mysql_query(‘set names utf8‘);
            mysql_query(‘use ‘. $data[‘database‘]);
        }

    }

 

可以实现客户端请求后,服务器立马返回数据,通知客户端请求成功。再子进程处理。而且不会有defunct僵尸进程。

socket + pcntl_fork 实现客户端请求,服务器实时监听返回处理 消息推送,布布扣,bubuko.com

时间: 2024-11-23 19:49:27

socket + pcntl_fork 实现客户端请求,服务器实时监听返回处理 消息推送的相关文章

基于socket.io的实时消息推送

用户访问Web站点的过程是基于HTTP协议的,而HTTP协议的工作模式是:请求-响应,客户端发出访问请求,服务器端以资源数据响应请求. 也就是说,服务器端始终是被动的,即使服务器端的资源数据发生变化,如果没有来自客户端的请求,用户就不会看到这些变化. 这种模式是不适合某些应用场景的,比如在社交网络用户需要近乎实时地知道其他用户最新的信息.对于普通站点来说, 请求-响应模式可以满足绝大多数的功能需求,但总有某些功能我们希望能够为用户提供实时消息的体验. 为解决这个问题,有两种方案可以选择: 仍旧使

ICE学习第四步-----客户端请求服务器返回数据

这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上. 根据上一篇文章介绍的Slice语法,我们先来定义ICE文件.我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法. 结构如下:    定义结构体,和数据库中表的列对应,添加序列(相当于数组类型). 在获取表的方法中注意要记得#include带有结构的ice文件,并把接口函数的返回值类型写成之前定义的数组

基于TCP网络通信的自动升级程序源码分析-客户端请求服务器上的升级信息

每次升级,客户端都会获取服务器端存放在upgradefile文件夹下的需要升级的文件和升级信息配置文件(即upgradeconfig.xml文件) 我们来看一下代码 //升级信息配置文件相对应的类 ( 升级信息配置文件是由这个类转化成的) private UpgradeConfig upgradeConfig = null; //客户端存储升级配置文件的地址 是放在客户端根目录下的 (就是把服务器 upgradefile/upgradeconfig.xml下载到客户端存放的位置) string

服务器与客户端消息推送的原理

其实服务端与客户端实现消息推送的方式有几种: 1.客户端不断的查询服务器,检查新的内容,也就是所谓的pull或者轮询的方式: 2.客户端与服务器之间维持一个TCP/IP长连接(在HTTP1.1中,所有的请求都认为是长连接),服务器向客户端push: 3.当服务端有新内容的时候,发送一条类似短信的信令给客户端,客户端收到货从服务器下载新内容,也就是SMS的推送方式: 对于第一种方式有以下的缺点: 1.因为需要不断地轮询,所以手机会很耗电: 2.容易被系统杀死: 对于第二种方式: 我们首先来了解一下

C# Socket基础(一)之启动异步服务监听

本文主要是以代码为主..NET技术交流群 199281001 .欢迎加入. //通知一个或多个正在等待的线程已发生事件. ManualResetEvent manager = new ManualResetEvent(false); 1 //负责监听的套接字 private Socket socketServer; 2 /// <summary> 3 /// 启动服务 4 /// </summary> 5 private void CreateSocketService() 6 {

Rsync+Inotify实时监听备份

说明,下面的inotify是建立在rsync的配置过程 大前提是rsync daemon 配置成功,rsync配置看上一遍博文,在客户端可以推拉数据,然后才能配置inotify服务----inotify是在客户端安装,监听需要备份的目录,然后推送到服务端 查看当前系统是否支持inotify [[email protected] bier]# uname -r 2.6.32-431.el6.i686 [[email protected] bier]# ls -l /proc/sys/fs/inot

sql server 警报管理,实时监听数据库动向,运筹帷幄之中

原文:sql server 警报管理,实时监听数据库动向,运筹帷幄之中 工作这么多年了,无论是身边的同学还是同事,发现只要搞程序员的都有一个通病---懒.懒到谁都不愿意加班,尤其是"义务"加班.即使大家都不愿意加班,但是很多时候项目赶着上线或者上线之后出错啊什么的,总得有人看着,这时候就诞生了一种新的工作制度,叫做7*24.顾名思义就是这种岗位实时都得有人看着,这确实是一件让人头疼的事情.虽然说在项目刚上线不可避免的得有7*24,但是我们可以尽量减少7*24的工作量(ps:因为7*24

移动端用js与jquery实时监听输入框值的改动

背景: 在一次移动端H5开发中,需要监听输入框值的实时变动. onchange事件肯定抛弃,因为只能失去焦点才触发. 而keyPress在Android可以触发,iOS不可以. 又不想用Android和iOS都可以触发的keyDown和keyUp. 于是,百度出了新东西:oninput![需要配合propertychange,兼容 IE9 以下版本] 用法: JS: if(isIE) { document.getElementById("input").onpropertychange

js/jquery 实时监听输入框值变化的完美方案:oninput &amp; onpropertychange

本文转载于 http://blog.163.com/lgh_2002/blog/static/44017526201341511112874/ Jquery绑定事件(bind和live的区别) js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange 2013-05-15 11:01:12|  分类: jquery/javascrip |