getSocketId函数:
function getSocketId($socket) { //socketId由socket中的地址和端口号拼接,这样可以保证socket的唯一性,又可以通过id快速读取保存socket的信息以及其附加的其他相关信息 if (socket_getpeername($socket, $address, $port) === FALSE) { return false; } return $address . '_' . $port; }
addSocket函数:
function addSocket($socket) { //将socket添加到已接受的socket连接池中 array_push($this->socketList, $socket); $socketId = $this->getSocketId($socket); //以socketId为索引建立socket映射表,便于后续快速处理socket相关信息 $this->socketListMap[$socketId] = array( //读取缓冲区,由于可能存在分帧的情况,此处统一先保存到缓冲区中,带收到结束帧后统一处理缓冲区 'buffer' => '', //握手成功标识,addSocket在接受连接后调用,故此时并未进行握手,初始化为false 'handshake' => false, //最后通信时间,用于判断超时断开操作 'lastCommuicate' => time(), //socket实例 'socket' => $socket, //错误计数 'errorCnt' => 0 ); }
removeSocket函数:
function removeSocket($socketId) { $socket = $this->socketListMap[$socketId]['socket']; //找出socket在socketList中的索引 $socketIndex = array_search($socket, $this->socketList); if ($this->debug) { echo "RemoveSocket at $socketIndex\n"; } //移除socketList中的socket array_splice($this->socketList, $socketIndex, 1); //移除socketListMap中的相关信息 unset($this->socketListMap[$socketId]); //回调事件 $this->onAfterRemoveSocket($socketId); }
socketAccept函数:
function socketAccept() { //接受socket $socket = socket_accept($this->serverSocket); if ($socket !== FALSE) { return $socket; } else if ($this->debug) { echo $this->getLastErrMsg(); } }
socketRecv函数:
//从指定socket中读取数据 function socketRecv($socketId) { $socket = $this->socketListMap[$socketId]['socket']; $bufferLen = socket_get_option($socket, SOL_SOCKET, SO_RCVBUF); $recv = socket_recv($socket, $buffer, $bufferLen, 0); if ($recv === FALSE) { $errCode = $this->getLastErrCode($socketId); $this->onerror($errCode, $socketId); if ($this->debug) { echo $this->getLastErrMsg(null, $errCode); } return NULL; } else if ($recv > 0) { if ($this->debug) { echo "Recv:\n"; $this->showData($buffer); } $this->socketListMap[$socketId]['lastCommuicate'] = time(); } return $buffer; }
socketSend函数:
function socketSend($socketId, $data) { $socket = $this->socketListMap[$socketId]['socket']; if ($this->debug) { echo "Send:\n"; $this->showData($data); } if (socket_write($socket, $data, strlen($data)) > 0) { $this->socketListMap[$socketId]['lastCommuicate'] = time(); } }
socketClose函数:
function socketClose($socketId) { $socket = $this->socketListMap[$socketId]['socket']; socket_close($socket); }
connect函数:
function connect($socket) { $this->addSocket($socket); $this->onconnected($socket); }
disconnectBySocket函数:
//此函数通过遍历查找socket信息,性能较低,不建议使用,通常使用disconnect直接根据socketId断开连接 //此函数通常用于一些异常socket的处理 function disconnectBySocket($socket) { $socketIndex = array_search($socket, $this->socketList); foreach ($this->socketListMap as $socketId => $session) { if ($session['socket'] == $socket) { $this->disconnect($socketId); return; } } }
disconnect函数:
function disconnect($socketId, $silent = false) { $this->socketClose($socketId); if (!$silent) { $this->ondisconnected($socketId); } $this->removeSocket($socketId); }