thinkphp socket to support sso (php socket 不稳定,不建议使用)

cli code
#!/bin/bash

filepath=$(cd "$(dirname "$0")"; pwd)
cd $filepath
#running status:sso.lock,stop status:ssostop.lock
TMPFILE=$filepath/sso.lock
STOPFILE=$filepath/ssostop.lock
runCLI(){
    touch $TMPFILE
    echo "sso server process started.\n"
    logname="sso_"$(date +%Y%m%d);
	su www-data -c "php index.php sso start 1>>./Log/$logname.log 2>&1"
    rm -f $STOPFILE;
}

restartCLI(){
    stopCLI
    echo "Waiting for stop sso process."
    sleep 1
    echo "Exit prev sso process."
    runCLI &    
}

stopCLI(){
    if [ -f $TMPFILE ];then
        touch $STOPFILE
    fi
    rm -f ${TMPFILE};
	logname="sso_"$(date +%Y%m%d);
	su www-data -c "php index.php sso stop 1>>./Log/$logname.log 2>&1"
    echo "Sent stop sso server signal."
}

if [ "$1" = "-stop" ] ;then
    stopCLI
elif [ "$1" = "-start" -o "$1" = "" ] ;then
    if [ -f $TMPFILE ];then
        echo "Another process is running."
    else
      runCLI &
    fi
elif [ "$1" = "-restart" ] ;then
    restartCLI
else
    echo "Please select option -start -restart -stop"
fi



socket server code
<?php
namespace Admin\Action;
use Think\Action;
class SsoAction extends Action {
	private $sock;
	private $clients = array();
// 停止socket。kill 后,有可能socket临时文件还是没删除。会导致同一个端口无法启动
	//check port status:netstat -ano |grep port
	//search pid: lsof -i:port 
	//kill pid
	//rm -f sso.lock
	public function run($taskType) 
	{
		switch ($taskType) {
			case 'start':
				$this->_start();
				break;
			default:
				echo datetime() . " unknow task type!" . PHP_EOL;
				break;
		}
	}
	
	public function index() {
		echo datetime() . " server msg: ". $_SERVER['argv'][1] . " " . $_SERVER['argv'][2] . PHP_EOL;
		$this->run($_SERVER['argv'][2]);
	}
	
	private function _start() 
	{
		set_time_limit(0);
		ob_implicit_flush();
		
		if (($this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
			echo datetime() . " socket_create() failed: reason:" . socket_strerror(socket_last_error()) . "\n";
			exit;
		}
		
		// start
		if (socket_bind($this->sock, C('SSO_ADDRESS'), C('SSO_PORT')) === false) {
			echo datetime() . " socket_bind failed, reason:" . socket_strerror(socket_last_error($sock)) . PHP_EOL;
			exit;
		}
		
		// listen
		if (socket_listen($this->sock, 5) === false) {
			echo datetime() . " socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
			exit;
		}
		echo datetime() . " start socket server success!" . PHP_EOL;
		do {
			// accept socket msg failed
			if (($msgsock = socket_accept($this->sock)) === false) {
				echo datetime() . " socket_accepty() failed :reason:" . socket_strerror(socket_last_error($this->sock)) . PHP_EOL;
				break;
			}
			//read client message
			$buf = socket_read($msgsock, 1024);
			$data = json_decode($buf, true);
			$userID = $data['userID'];
			if ($data['msg'] == 'logout') {
				// clear session table 
				$this->_logout($userID);
		    } elseif ($data['msg'] == "check") {
		    	// check cache with user ID
		    	$back = S($userID) ? "success" : "fail";
				echo datetime() . " no cache of {$userID} " . PHP_EOL;
				if (false === socket_write($msgsock, $back)) {
					echo datetime() . " socket_write() failed reason:" . socket_strerror(socket_last_error($this->sock)) . PHP_EOL;
				}
		    }
			socket_close($msgsock);
		} while (true);
	}
	
	private function _logout($userID) {
		if (!$userID) return false;
		S($userID, null);
		echo datetime() . " userID:{$userID} logout by client. " . PHP_EOL;
	}
}
?>


socket client code
<?php
namespace Admin\Action;
 use Think\Action;
 use Org\Util\Socket;
class SsoClientAction extends Action {
	private $SocketClient;
	/**
	 * loop check sso server auth status
	 */
	public function run() 
	{
		$result = true;
		while($result===true) {
		    $this->_connect();	
			$result = $this->send();
			if (!$result) {
				// logout 
				session_destroy();
			}
			sleep(3);
		} 
		//$this->_connect();	
		//$result = $this->send();
	}

	private function _connect()
	{
		$config = array('persistent'	=> false,
						'host'			=> C("SSO_ADDRESS"),
						'protocol'		=> 'tcp',
						'port'			=> C("SSO_PORT"),
						'timeout'		=> 5);
		$this->SocketClient = new Socket($config);
		$this->SocketClient->connect();
	}
	
	/**
	 * @param msg check or logout string
	 */
	public function send($msg="check")
	{
		$userID = $_SESSION[C('USER_AUTH_KEY')];
		if (!$userID) $msg = "logout";
		$arr = array("msg"=>$msg, $userID=>$userID);
		$data = json_encode($arr);
		$result = $this->SocketClient->write($data);
		//echo datetime() . " send msg:{$msg} \r\n"  . PHP_EOL;
		$response = $this->SocketClient->read();
		echo datetime() . " " . $response . " from sso server \r\n" . PHP_EOL;
		$this->SocketClient->disconnect();
		if ($response == "logout" || $response == "fail") {
			echo datetime . " logout or fail \r\n" . PHP_EOL;
			session_destroy();
			return false;
		} 
		return true;
	}
}
?>

猜你喜欢

转载自lhdst-163-com.iteye.com/blog/2236266