struct GatewayProtocol
{
unsigned int pack_len,
unsigned char cmd,//命令字
unsigned int local_ip,
unsigned short local_port,
unsigned int client_ip,
unsigned short client_port,
unsigned int client_id,
unsigned char flag,
unsigned int ext_len,
char[ext_len] ext_data,
char[pack_length-HEAD_LEN] body//包体
}
/** * 初始化 * @return void */ public function __construct($buffer = null) { if ($buffer) { $data = self::decode($buffer); $this->body = $data['body']; unset($data['body']); $this->header = $data; } else { if (self::$seriesId >= 65535) { self::$seriesId = 0; } else { $this->header['series_id'] = self::$seriesId++; } } }
/** * 发送数据到网关 * @param string $address * @param string $buffer */ protected static function sendToGateway($address, $gateway_data) { // 有$businessWorker说明是workerman环境,使用$businessWorker发送数据 if (self::$businessWorker) { if (!isset(self::$businessWorker->gatewayConnections[$address])) { return false; } return self::$businessWorker->gatewayConnections[$address]->send($gateway_data); } // 非workerman环境,使用udp发送数据 $gateway_buffer = GatewayProtocol::encode($gateway_data); $client = stream_socket_client("udp://{$address}", $errno, $errmsg); return strlen($gateway_buffer) == stream_socket_sendto($client, $gateway_buffer); }
protected function sendToWorker($cmd, $socket_id, $body = '') { $address = $this->getRemoteAddress($socket_id); list($client_ip, $client_port) = explode(':', $address, 2); if (empty($client_port)) { $this->notice(new Exception('$address empty :' . var_export($address, true)) . ' $this->connections:' . var_export($this->connections, true) . ' this->protocol:' . $this->protocol); } $pack = new GatewayProtocol(); $pack->header['cmd'] = $cmd; $pack->header['local_ip'] = $this->lanIp; $pack->header['local_port'] = $this->lanPort; $pack->header['socket_id'] = $socket_id; $pack->header['client_ip'] = $client_ip; $pack->header['client_port'] = $client_ip; $pack->header['uid'] = $this->getUidByFd($socket_id); $pack->body = $body; return $this->sendBufferToWorker($pack->getBuffer()); }
/** * 踢掉某个网关的socket * @param string $local_ip * @param int $local_port * @param int $socket_id * @param string $message * @param int $uid */ public static function kickAddress($local_ip, $local_port, $socket_id, $message, $uid = null) { $pack = new GatewayProtocol(); $pack->header['cmd'] = GatewayProtocol::CMD_KICK; $pack->header['series_id'] = Context::$series_id > 0 ? Context::$series_id : 0; $pack->header['local_ip'] = $local_ip; $pack->header['local_port'] = $local_port; $pack->header['socket_id'] = $socket_id; if (null !== Context::$client_ip) { $pack->header['client_ip'] = Context::$client_ip; $pack->header['client_port'] = Context::$client_port; } $pack->header['uid'] = $uid ? $uid : 0; $pack->body = $message; return self::sendToGateway("udp://{$pack->header['local_ip']}:{$pack->header['local_port']}", $pack->getBuffer()); }
public function dealInput($recv_str) { return GatewayProtocol::input($recv_str); }