电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

用PHP的Socket建立自己的聊天室服務(wù)器

瀏覽:3日期:2024-02-21 13:02:42

<?PHP/*** patServer* PHP socket server base class* Events that can be handled:** onStart** onConnect** onConnectionRefused** onClose** onShutdown** onReceiveData** @version 1.1* @authorStephan Schmidt <schst@php-tools.de>* @package patServer*/class patServer{/*** information about the project* @var array $systemVars*/var $systemVars= array(

'appName'=> 'patServer', 'appVersion'=> '1.1', 'author'=> array('Stephan Schmidt <schst@php-tools.de>', ) );

/*** port to listen* @var integer$port*/ var $port= 10000;

/*** domain to bind to* @var string $domain*/ var $domain= 'localhost';

/*** maximum amount of clients* @var integer $maxClients*/ var $maxClients = -1;

/*** buffer size for socket_read* @var integer $readBufferSize*/ var $readBufferSize= 128;

/*** end character for socket_read* @var integer $readEndCharacter*/ var $readEndCharacter = 'n';

/*** maximum of backlog in queue* @var integer $maxQueue*/ var $maxQueue = 500;

/*** debug mode* @var boolean $debug*/ var $debug= true;

/*** debug mode* @var string $debugMode*/ var $debugMode = 'text';

/*** debug destination (filename or stdout)* @var string $debugDest*/ var $debugDest = 'stdout';

/*** empty array, used for socket_select* @var array $null*/ var $null= array();

/*** all file descriptors are stored here* @var array $clientFD*/ var $clientFD = array();

/*** needed to store client information* @var array $clientInfo*/ var $clientInfo = array();

/*** needed to store server information* @var array $serverInfo*/ var $serverInfo = array();

/*** amount of clients* @var integer$clients*/ var $clients = 0;

/*** create a new socket server** @access public* @param string$domaindomain to bind to* @param integer$portport to listen to*/function patServer( $domain = 'localhost', $port = 10000 ){ $this->domain = $domain; $this->port= $port;

$this->serverInfo['domain'] = $domain; $this->serverInfo['port'] = $port; $this->serverInfo['servername'];;= $this->systemVars['appName']; $this->serverInfo['serverversion'] = $this->systemVars['appVersion'];

set_time_limit( 0 );}

/*** set maximum amount of simultaneous connections** @access public* @param int $maxClients*/function setMaxClients( $maxClients ){ $this->maxClients = $maxClients;}

/*** set debug mode** @access public* @param mixed $debug [text|htmlfalse]* @param string $dest destination of debug message (stdout to output or filename if log should be written)*/function setDebugMode( $debug, $dest = 'stdout' ){ if( $debug === false ){ $this->debug = false; return true; }

$this->debug= true; $this->debugMode = $debug; $this->debugDest = $dest;}

/*** start the server** @access public* @param int $maxClients*/function start(){ $this->initFD = @socket_create( AF_INET, SOCK_STREAM, 0 ); if( !$this->initFD ) die( 'patServer: Could not create socket.' );

// adress may be reused socket_setopt( $this->initFD, SOL_SOCKET, SO_REUSEADDR, 1 );

// bind the socket if(!@socket_bind( $this->initFD, $this->domain, $this->port ) ){ @socket_close( $this->initFD ); die( 'patServer: Could not bind socket to '.$this->domain.' on port '.$this->port.' ( '.$this->getLastSocketError( $this->initFd ).' ).' ); }

// listen on selected port if(!@socket_listen( $this->initFD, $this->maxQueue ) ) die( 'patServer: Could not listen ( '.$this->getLastSocketError( $this->initFd ).' ).' );

$this->sendDebugMessage( 'Listening on port '.$this->port.'. Server started at '.date( 'H:i:s', time() ) );

// this allows the shutdown function to check whether the server is already shut down $GLOBALS['_patServerStatus'] = 'running'; // this ensures that the server will be sutdown correctly register_shutdown_function( array( $this, 'shutdown' ) );

if( method_exists( $this, 'onStart' ) ) $this->onStart();

$this->serverInfo['started'] = time(); $this->serverInfo['status']= 'running';

while( true ){ $readFDs = array(); array_push( $readFDs, $this->initFD );

// fetch all clients that are awaiting connections for( $i = 0; $i < count( $this->clientFD ); $i++ ) if( isset( $this->clientFD[$i] ) ) array_push( $readFDs, $this->clientFD[$i] );

// block and wait for data or new connection $ready = @socket_select( $readFDs, $this->null, $this->null, NULL );

if( $ready === false ){ $this->sendDebugMessage( 'socket_select failed.' ); $this->shutdown(); }

// check for new connection if( in_array( $this->initFD, $readFDs ) ){ $newClient = $this->acceptConnection( $this->initFD );

// check for maximum amount of connections if( $this->maxClients > 0 ){ if( $this->clients > $this->maxClients ){ $this->sendDebugMessage( 'Too many connections.' );

if( method_exists( $this, 'onConnectionRefused' ) ) $this->onConnectionRefused( $newClient );

$this->closeConnection( $newClient ); } }

if( --$ready <= 0 ) continue; }

// check all clients for incoming data for( $i = 0; $i < count( $this->clientFD ); $i++ ){ if( !isset( $this->clientFD[$i] ) ) continue;

if( in_array( $this->clientFD[$i], $readFDs ) ){ $data = $this->readFromSocket( $i );

// empty data => connection was closed if( !$data ){ $this->sendDebugMessage( 'Connection closed by peer' ); $this->closeConnection( $i ); }else{ $this->sendDebugMessage( 'Received '.trim( $data ).' from '.$i );

if( method_exists( $this, 'onReceiveData' ) ) $this->onReceiveData( $i, $data ); } } } }}

/*** read from a socket** @access private* @param integer $clientId internal id of the client to read from* @return string $datadata that was read*/function readFromSocket( $clientId ){ // start with empty string $data= '';

// read data from socket while( $buf = socket_read( $this->clientFD[$clientId], $this->readBufferSize ) ){ $data .= $buf;

$endString = substr( $buf, - strlen( $this->readEndCharacter ) ); if( $endString == $this->readEndCharacter ) break; if( $buf == NULL ) break; }

if( $buf === false ) $this->sendDebugMessage( 'Could not read from client '.$clientId.' ( '.$this->getLastSocketError( $this->clientFD[$clientId] ).' ).' );

return $data;}

/*** accept a new connection** @access public* @param resource &$socket socket that received the new connection* @return int;$clientID internal ID of the client*/function acceptConnection( &$socket ){ for( $i = 0 ; $i <= count( $this->clientFD ); $i++ ){ if( !isset( $this->clientFD[$i] ) || $this->clientFD[$i] == NULL ){ $this->clientFD[$i] = socket_accept( $socket ); socket_setopt( $this->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1 ); $peer_host = ''; $peer_port = ''; socket_getpeername( $this->clientFD[$i], $peer_host, $peer_port ); $this->clientInfo[$i] = array( 'host'=> $peer_host, 'port'=> $peer_port, 'connectOn' => time() ); $this->clients++;

$this->sendDebugMessage( 'New connection ( '.$i.' ) from '.$peer_host.' on port '.$peer_port );

if( method_exists( $this, 'onConnect' ) ) $this->onConnect( $i ); return $i; } }}

/*** check, whether a client is still connected** @access public* @param integer $id client id* @return boolean $connected true if client is connected, false otherwise*/function isConnected( $id ){ if( !isset( $this->clientFD[$id] ) ) return false; return true;}

/*** close connection to a client** @access public* @param int $clientID internal ID of the client*/function closeConnection( $id ){ if( !isset( $this->clientFD[$id] ) ) return false;

if( method_exists( $this, 'onClose' ) ) $this->onClose( $id );

$this->sendDebugMessage( 'Closed connection ( '.$id.' ) from '.$this->clientInfo[$id]['host'].' on port '.$this->clientInfo[$id]['port'] );

@socket_close( $this->clientFD[$id] ); $this->clientFD[$id] = NULL; unset( $this->clientInfo[$id] ); $this->clients--;}

/*** shutdown server** @access public*/function shutDown(){ if( $GLOBALS['_patServerStatus'] != 'running' ) exit; $GLOBALS['_patServerStatus'] = 'stopped';

if( method_exists( $this, 'onShutdown' ) ) $this->onShutdown();

$maxFD = count( $this->clientFD ); for( $i = 0; $i < $maxFD; $i++ ) $this->closeConnection( $i );

@socket_close( $this->initFD );

$this->sendDebugMessage( 'Shutdown server.' ); exit;}

/*** get current amount of clients** @access public* @return int $clients amount of clients*/function getClients(){ return $this->clients;}

/*** send data to a client** @access public* @param int$clientId ID of the client* @param string $datadata to send* @param boolean $debugData flag to indicate whether data that is written to socket should also be sent as debug message*/function sendData( $clientId, $data, $debugData = true ){ if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL ) return false;

if( $debugData ) $this->sendDebugMessage( 'sending: '' . $data . '' to: $clientId' );

if(!@socket_write( $this->clientFD[$clientId], $data ) ) $this->sendDebugMessage( 'Could not write ''.$data.'' client '.$clientId.' ( '.$this->getLastSocketError( $this->clientFD[$clientId] ).' ).' );}

/*** send data to all clients** @access public* @param string $datadata to send* @param array $exclude client ids to exclude*/function broadcastData( $data, $exclude = array(), $debugData = true ){ if( !empty( $exclude ) && !is_array( $exclude ) ) $exclude = array( $exclude );

for( $i = 0; $i < count( $this->clientFD ); $i++ ){ if( isset( $this->clientFD[$i] ) && $this->clientFD[$i] != NULL && !in_array( $i, $exclude ) ){ if( $debugData ) $this->sendDebugMessage( 'sending: '' . $data . '' to: $i' );

if(!@socket_write( $this->clientFD[$i], $data ) ) $this->sendDebugMessage( 'Could not write ''.$data.'' client '.$i.' ( '.$this->getLastSocketError( $this->clientFD[$i] ).' ).' ); } }}

/*** get current information about a client** @access public* @param int$clientId ID of the client* @return array $infoinformation about the client*/function getClientInfo( $clientId ){ if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL ) return false; return $this->clientInfo[$clientId];}

/*** send a debug message** @access private* @param string $msg message to debug*/function sendDebugMessage( $msg ){ if( !$this->debug ) return false;

$msg = date( 'Y-m-d H:i:s', time() ) . ' ' . $msg;

switch( $this->debugMode ){ case 'text': $msg = $msg.'n'; break; case 'html': $msg = htmlspecialchars( $msg ) . '<br />n'; break; }

if( $this->debugDest == 'stdout' || empty( $this->debugDest ) ){ echo $msg; flush(); return true; }

error_log( $msg, 3, $this->debugDest ); return true;}

/*** return string for last socket error** @access public* @return string $error last error*/function getLastSocketError( &$fd ){ $lastError = socket_last_error( $fd ); return 'msg: ' . socket_strerror( $lastError ) . ' / Code: '.$lastError;}function onReceiveData($ip,$data){ $this->broadcastData( $data,array(), true );}}$patServer = new patServer();$patServer->start();?>

標(biāo)簽: PHP
主站蜘蛛池模板: 煤矿人员精确定位系统_矿用无线通信系统_煤矿广播系统 | 自动焊锡机_点胶机_螺丝机-锐驰机器人 | 恒压供水控制柜|无负压|一体化泵站控制柜|PLC远程调试|MCGS触摸屏|自动控制方案-联致自控设备 | 建筑资质代办-建筑企业资质代办机构-建筑资质代办公司 | 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | 上海公司注册-代理记账-招投标审计-上海昆仑扇财税咨询有限公司 上海冠顶工业设备有限公司-隧道炉,烘箱,UV固化机,涂装设备,高温炉,工业机器人生产厂家 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | 水轮机密封网 | 水轮机密封产品研发生产厂家 | 陕西视频监控,智能安防监控,安防系统-西安鑫安5A安防工程公司 | 深圳市简易检测技术有限公司| 隆众资讯-首页_大宗商品资讯_价格走势_市场行情 | 【ph计】|在线ph计|工业ph计|ph计厂家|ph计价格|酸度计生产厂家_武汉吉尔德科技有限公司 | 搪瓷搅拌器,搪玻璃搅拌器,搪玻璃冷凝器_厂家-淄博越宏化工设备 | 超声波清洗机_细胞破碎仪_实验室超声仪器_恒温水浴-广东洁盟深那仪器 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 心得体会网_心得体会格式范文模板| 软文推广发布平台_新闻稿件自助发布_媒体邀约-澜媒宝 | 对辊式破碎机-对辊制砂机-双辊-双齿辊破碎机-巩义市裕顺机械制造有限公司 | 干粉砂浆设备_干混砂浆生产线_腻子粉加工设备_石膏抹灰砂浆生产成套设备厂家_干粉混合设备_砂子烘干机--郑州铭将机械设备有限公司 | 丹佛斯压力传感器,WISE温度传感器,WISE压力开关,丹佛斯温度开关-上海力笙工业设备有限公司 | 球磨机,节能球磨机价格,水泥球磨机厂家,粉煤灰球磨机-吉宏机械制造有限公司 | 深圳宣传片制作_产品视频制作_深圳3D动画制作公司_深圳短视频拍摄-深圳市西典映画传媒有限公司 | 颚式破碎机,圆锥破碎机,制砂机-新乡市德诚机电制造有限公司 | 减速机三参数组合探头|TSM803|壁挂式氧化锆分析仪探头-安徽鹏宸电气有限公司 | 噪声治理公司-噪音治理专业隔音降噪公司 | 丹佛斯变频器-丹佛斯压力开关-变送器-广州市风华机电设备有限公司 | 【连江县榕彩涂料有限公司】官方网站| 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | 华溶溶出仪-Memmert稳定箱-上海协烁仪器科技有限公司 | LZ-373测厚仪-华瑞VOC气体检测仪-个人有毒气体检测仪-厂家-深圳市深博瑞仪器仪表有限公司 | 仓储笼_金属箱租赁_循环包装_铁网箱_蝴蝶笼租赁_酷龙仓储笼租赁 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 磁粉制动器|张力控制器|气胀轴|伺服纠偏控制器整套厂家--台灵机电官网 | 上海赞永| 黄石东方妇产医院_黄石妇科医院哪家好_黄石无痛人流医院 | 中天寰创-内蒙古钢结构厂家|门式刚架|钢结构桁架|钢结构框架|包头钢结构煤棚 | 起好名字_取个好名字_好名网免费取好名在线打分 | 新车测评网_网罗汽车评测资讯_汽车评测门户报道 | 无锡装修装潢公司,口碑好的装饰装修公司-无锡索美装饰设计工程有限公司 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 |