点击(此处)折叠或打开
-
<?php
-
//守护进程化
-
daemonize();
-
-
//建立socket绑定
-
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0)
-
{
-
echo "failed to create socket: ".socket_strerror($sock)."\n";
-
exit();
-
}
-
$address = "192.168.84.72";
-
$port = 9998;
-
if(($ret = socket_bind($sock, $address, $port)) < 0)
-
{
-
echo "failed to bind socket: ".socket_strerror($ret)."\n";
-
exit();
-
}
-
if( ( $ret = socket_listen( $sock, 0 ) ) < 0 )
-
{
-
echo "failed to listen to socket: ".socket_strerror($ret)."\n";
-
exit();
-
}
-
socket_set_nonblock($sock);
-
while (true)
-
{
-
$conn = @socket_accept($sock);
-
if( $conn === false ) {
-
usleep(1000);
-
} elseif( $conn > 0 ){
-
-
$pid = pcntl_fork();
-
//子进程
-
if($pid == 0)
-
{
-
//关闭socket监听
-
socket_close($sock);
-
include('redis.php');
-
socket_set_nonblock($conn);
-
-
//维护在线列表
-
$redis->sadd('online',(int)$conn);
-
while ($conn) {
-
//数据不为空进入队列
-
$recv = socket_read($conn, 1024);
-
if( !empty($recv) ) {
-
$send_data=$recv;
-
if($recv=="bye\r\n") {
-
socket_close($conn);
-
$redis->srem('oncline',(int)$conn);
-
exit(0);
-
}
-
$online = $redis->smembers('online');
-
if(!empty($online)) {
-
foreach($online as $one) {
-
if($one != (int)$conn){
-
$redis->lpush('chats_'.$one,$send_data);
-
}
-
}
-
}
-
}
-
-
//在队列中循环读消息
-
$msg = $redis->rpop('chats_'.(int)$conn);
-
if( !empty($msg) ) {
-
socket_write($conn,$msg);
-
}
-
usleep(1000);
-
}
-
}
-
else
-
{
-
//记录子进程id
-
$son_process_id[]=$pid;
-
socket_close($conn);
-
}
-
} else {
-
echo "error: ".socket_strerror($conn);
-
die;
-
}
-
}
-
-
function daemonize()
-
{
-
$pid = pcntl_fork();
-
if ($pid == -1)
-
{
-
die("fork(1) failed!\n");
-
}
-
elseif ($pid > 0)
-
{
-
//让由用户启动的进程退出
-
exit(0);
-
}
-
-
//建立一个有别于终端的新session以脱离终端
-
posix_setsid();
-
-
$pid = pcntl_fork();
-
if ($pid == -1)
-
{
-
die("fork(2) failed!\n");
-
}
-
elseif ($pid > 0)
-
{
-
//父进程退出, 剩下子进程成为最终的独立进程
-
exit(0);
-
}
-
}
-
- ?>
点击(此处)折叠或打开
-
<?php
-
$ip = "127.0.0.1";
-
$port = 6378;
-
$redis = new Redis();
-
$redis->pconnect($ip, $port);
- ?>