websocket - php 实现了进程间通信后该如何实现网络通信??
黄舟
黄舟 2017-04-11 09:23:12
0
2
368

php 实现了进程间通信后该如何实现网络通信??

我暂时使用的进程间通信方式是:System v 消息队列

问题:如果我要把这个东西弄到网站上去,实现网络即时通信功能,该怎么做??这个问题的答案我感觉内容会很多,如果你知道,请一定别吝啬时间,把答案写成一篇文章,或者你在自己的博客啥的中写一篇文章,然后发个链接给我,对我来说有用!百分之百有用!谢谢

我写了一个生成 msg_get_queue($key) 中 $key 的类:

/*
 *********************************
 工作原理介绍
 这只是一个生成 msg_get_queue($key) 中 $key 的一个类。所有创建的 key 和其 状态都会保存在 
 key.key 这个文件中。key.key 这个文件的格式如下:
     1234567890 free
 第一个数字表示消息队列的 key;第二个是消息队列的状态,允许值:running | free。如果只有一
 个进程在使用消息队列,那么这个消息队列的状态为free,表示该消息队列是空闲的,即允许再有一
 个进程来使用这个消息队列,以实现一对一通信。两个进程在使用这个消息队列,此时以满足一对一
 对一通信要求,状态修改为:running

 先说一下通过消息队列方式进行进程间通信的步骤(A , B 两个进程间通信,类别:一对一通信):
 1. 建立连接
    1.1 A 创建或使用一个消息队列(key 是找到这个消息队列的唯一途径),并且发送消息
        创建后,在 key.key 这个文件中会生成一条记录: 1234567890 free
    1.2 B 接受消息,使用 key 实现对 A 发送消息的接收。由于步骤1.1 已创建
        key = 1234567890 的消息队列,所以这边是使用已存在的消息队列,至此
        一对一连接创建成功。修改 key = 1234567890 这个消息队列的状态为 running
 2. 退出连接
    2.1 进程退出时,如果 key 的状态为 running,则表示此时有两个进程在使用消息队列,退
        出一个后,修改该 key = 1234567890 的状态为 free。如果为 free,则直接从key.key
        文件中删除这一行!
 
 缺陷:自动匹配连接,无法通过指定的 key 与指定的进程进行通信。
 ************************************
*/
class GenerateKey {
    public $keyFile = 'key.key';

    private function _getKeyInfo(int $key = 0000000000) {
        $f = fopen($this->keyFile , 'r');

        while ($line = fgets($f))
            {
                $data = trim($line);
                $data = explode(' ' , $data);
                $k  = intval($data[0]);

                if ($key === $k) {
                    fclose($f);

                    return Array(
                        'key' => $key , 
                        'status' => $data[1]
                    );
                }
            }

        return false;
    }

    // check key file exists
    private function _checkKeyFile(){
        if (!file_exists($this->keyFile)) {
            if (!($f = fopen($this->keyFile , 'x'))) {
                throw new Exception('create key file failed!' . PHP_EOL);
            }

            fclose($f);
        }

        return true;
    }

    // check key exists
    private function _checkKey(int $key = 0000000000) : bool {
        if (!$this->_getKeyInfo($key)) {
            return false;
        }

        return true;
    }


    // check key is running
    public function isRunning(int $key = 0000000000) : bool {
        $key_info = $this->_getKeyInfo($key);

        if (!$key_info) {
            return false;
        }

        return $key_info['status'] === 'running' ? true : false;
    }

    // if one of open process close then change the status
    // or both of open process close then remove the status
    public function rKey(int $key = 0000000000) : bool {
        if ($this->_checkKey($key)) {
            $f = fopen($this->keyFile , 'r+');
            $s_idx = 0;

            $content = file_get_contents($this->keyFile , false , null , 0 , filesize($this->keyFile));

            while ($line = fgets($f))
                {
                    $len = strlen($line);
                    $s_idx += $len;
                    $data = trim($line);
                    $data = explode(' ' , $data);
                    $k = intval($data[0]);
                    $status = $data[1];

                    if ($k === $key) {
                        if ($status === 'running') {
                            $replace_line = str_replace('running' , 'free' , $line);
                        } else if ($status === 'free') {
                            $replace_line = '';
                        } else {
                            exit;
                        }

                        $content = substr_replace($content , $replace_line , $s_idx - $len , $len);

                        fclose($f);

                        $f = fopen($this->keyFile , 'w');

                        fwrite($f , $content);
                        fclose($f);

                        return true;
                    }

                }

        }

        return true;
    }

    // msg queue: create keys
    public function cKey(String $key_file = '') : int {
        $key_file = !empty($key_file) ? $key_file : $this->keyFile;

        $this->keyFile = $key_file;
        $this->_checkKeyFile();

        $f = fopen($key_file , 'r+');

        flock($f , LOCK_EX);

        // data format(10)
        // key          status
        // 1879578547   running/free
        $index   = 0;
        $s_idx      = 0;
        $content = file_get_contents($key_file , false , null , 0 , filesize($key_file));
        $keys      = array();

        while ($line = fgets($f))
            {
                if (empty($line)) {
                    continue;
                }

                $index++;
                $len = strlen($line);
                $s_idx        += $len;
                $data         = trim($line);
                $data         =    explode(' ' , $data);
                $key          = intval($data[0]);
                $status     = $data[1];
                $keys[$key] = $status;

                if ($status === 'running') {
                    continue;
                }

                if ($status === 'free') {
                    $replace_line = str_replace('free' , 'running' , $line);
                    $content       = substr_replace($content , $replace_line , max(0 , $s_idx - $len) , $len);

                    flock($f , LOCK_UN);
                    fclose($f);

                    $f = fopen($key_file , 'w');

                    flock($f , LOCK_EX);
                    fwrite($f , $content);
                    flock($f , LOCK_UN);
                    fclose($f);

                    return $key;
                }
            }

        fclose($f);

        // stop the error was  produced
        set_error_handler(function(){});

        $wait_time = 20 * 1000;

        while (!($f = fopen($key_file , 'a')))
            {
                usleep($wait_time);
            }

        flock($f , LOCK_EX);

        $key     = intval(join('' , random(10 , 'number')));
        $status = 'free';

        while (array_key_exists($key , $keys))
            {
                $key = intval(join('' , random(10 , 'number')));
            }
        
        fwrite($f , $key . ' ' . $status . PHP_EOL);
        flock($f , LOCK_UN);
        fclose($f);

        // origin error hander
        restore_error_handler();

        return $key;
    }
}

效果如下图所示:

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

membalas semua(2)
Ty80

socket, 服务端请求客户端端口发送socket信息

Ty80
  1. websocket
    介绍 https://zh.wikipedia.org/wiki...
    websocket for php https://code.google.com/archi...

  2. http request,response。比较浪费带宽

http://www.ibm.com/developerw...

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!