class SocketServer{
private $socket; //socket资源句柄
private $userSocket = array(); //保存链接进来的套接字列表
private $writeSocket = array(); //保存链接进来的套接字列表
/**
*初始化
*@param String $host ip地址
*@param int $port 端口
*@param int $backlog 最大连接数
*/
public function __construct($host = '127.0.0.1',$port = '9337', $backlog = 10)
{
$this -> socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die('socket创建失败'); //创建socket
socket_bind($this -> socket,$host,$port); //为socket绑定端口
socket_listen($this -> socket,$backlog); //监听socket套接字并设置链接数 可以不设置
$socketkey = $this -> generateRangNum();
$this->userSocket[$socketkey] = $this -> socket; //把套接字保存到数组中
}
/**
*启动woker实例
*/
public function runStart() {
while(true) { //设置一个循环用来监听来自客户端的请求
$socketList = $this->userSocket; //把读的socket放到变量中
socket_select($socketList, $this->writeSocket , $except = null , null); //多路进行选择
foreach ( $socketList as $socket ) {
if($this->socket == $socket) { //说明当前的服务器监听socket //就开始设置请求的函数
$client = socket_accept($this->socket); //接收客户端的链接
//添加客户端套接字
$userkey = $this->_addClient($client);//把客户端的socket句柄添加到userSocket中
$data = array(
'success' => 'Welcome',
'info' => $userkey
);
$datajson = json_encode( $data );
socket_write($client,$datajson,strlen($datajson)); //触发链接后告诉客户端链接成功的信息
//$this->sendAll();
} else {
$msg = @socket_read($socket,1024);//获取客户端发送来的信息
$msginfo = json_decode( $msg,true );
if ( $msginfo['type'] =='all' ) { //发送所有人
$this->sendAll();
} else {
$this->sendToUser( $msginfo['userkey'],$msginfo['info'] );
}
}
}
}
}
/**
*@param resource $client 客户端的套接字
*/
private function _addClient($client) {
$socketkey = $this -> generateRangNum();
$this->userSocket[$socketkey] = $client;
return $socketkey;
}
//对单用户socket发送
public function sendToUser( $userkey,$info ) {
$socket = $this->userSocket[$userkey];
@socket_write($socket,$info,strlen( $info ));
}
//对所有socket发送
public function sendAll() {
$socketList = $this->userSocket;
foreach ($socketList as $socket) {
@socket_write($socket,'hai',strlen('hai'));
}
}
//生成唯一的key 用于单用户通信
public function generateRangNum() {
return md5(time() . mt_rand(1,1000000));
}
}
$s = new SocketServer();
$s -> runStart();