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);
}