Home > Article > Backend Development > How to use protobuf-php and socket
This article mainly shares with you how to use protobuf-php and socket. It mainly explains it to you in the form of code. I hope it can help you.
vi login.proto
package login; message ReqCheckVerifyVerLoginClient { required int32 game = 1; ///< 游戏类型编号 required bytes version = 2; ///< 游戏版本号} message AnsCheckVerifyVerLoginClient { required uint32 ret_code = 1; //返回码 optional uint32 forbid_flag = 2; //冻结时间 optional uint32 time_diff = 3; //剩余解封时间}
protoc --plugin=/usr/local/php/bin/protoc-gen-php --php_out=. -I. login.proto
Get login.php
namespace login { class ReqCheckVerifyVerLoginClient extends \DrSlump\Protobuf\Message { /** @var int */ public $game = null; /** @var string */ public $version = null; /** @var \Closure[] */ protected static $__extensions = array();.........
Use login.php
function.php
<?php/** * Created by PhpStorm. * User: Administrator * Date: 2018/3/23 * Time: 19:26 */require 'socket.php';require 'structNum.php';function socket($ip,$port,$packed){ try{ $socket = Socket::singleton(); $socket->connect($ip,$port); if(count($packed) >1){ foreach ($packed as $key){ $sockResult = $socket->sendRequest($key);// 将包发送给服务器 sleep(3); } } $getrepost = $socket->getResponse(); $socket->disconnect (); //关闭链接 } catch (Exception $e) { var_dump($e); $this->log_error(" error send to server".$e->getMessage()); } return $getrepost; }function unPackData($data){ $rev_len = unpack("L*",substr($data,0,4)); $rev_num = unpack("S*",substr($data,4,2)); $rev_data = substr($data,6,2); $data_array = array( 'num' =>$rev_num, 'data'=>$rev_data ); return $data_array; } $structNum;function StructNum($num){ $class = $GLOBALS['structNum'][$num]; return $class; }
socket.php
<?phpdefine("CONNECTED", true); define("DISCONNECTED", false); Class Socket { private static $instance; private $connection = null; private $connectionState = DISCONNECTED; private $defaultHost = "192.168.128.198"; private $defaultPort = 9301; private $defaultTimeOut = 60; public $debug = false; public function __construct() { } /** * Singleton pattern. Returns the same instance to all callers * * @return Socket */ public static function singleton() { if (self::$instance == null || ! self::$instance instanceof Socket) { self::$instance = new Socket(); } return self::$instance; } public function connect($serverHost=false,$serverPort=false,$timeOut=false) { if($serverHost == false) { $serverHost = $this->defaultHost; } if($serverPort == false) { $serverPort = $this->defaultPort; } $this->defaultHost = $serverHost; $this->defaultPort = $serverPort; if($timeOut == false) { $timeOut = $this->defaultTimeOut; } $this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if(socket_connect($this->connection,$serverHost,$serverPort) == false) { $errorString = socket_strerror(socket_last_error($this->connection)); $this->_throwError("Connecting to {$serverHost}:{$serverPort} failed.<br>Reason: {$errorString}"); }else{ $this->_throwMsg("Socket connected!"); } $this->connectionState = CONNECTED; } /** * Disconnects from the server * * @return True on succes, false if the connection was already closed */ public function disconnect() { if($this->validateConnection()) { socket_close($this->connection); $this->connectionState = DISCONNECTED; $this->_throwMsg("Socket disconnected!"); return true; } return false; } public function sendRequest($data) { if($this->validateConnection()) { $result = socket_write($this->connection,$data,strlen($data)); return $result; }else{ $this->_throwError("Sending command \"{$data}\" failed.<br>Reason: Not connected"); } } public function getResponse() { if($this->validateConnection()) { if( ($ret = socket_read($this->connection,8192)) == false){ $this->_throwError("Receiving response from server failed.<br>Reason: Not bytes to read"); return false; } else{ return $ret; } } } public function isConn() { return $this->connectionState; } public function getUnreadBytes() { $info = socket_get_status($this->connection); return $info['unread_bytes']; } public function getConnName(&$addr, &$port) { if ($this->validateConnection()) { socket_getsockname($this->connection,$addr,$port); } } public function waitForResponse() { if($this->validateConnection()) { return socket_read($this->connection, 2048); } $this->_throwError("Receiving response from server failed.<br>Reason: Not connected"); return false; } /** * Validates the connection state * * @return bool */ private function validateConnection() { return (is_resource($this->connection) && ($this->connectionState != DISCONNECTED)); } /** * Throws an error * * @return void */ private function _throwError($errorMessage) { echo "Socket error: " . $errorMessage; } /** * Throws an message * * @return void */ private function _throwMsg($msg) { if ($this->debug) { echo "Socket message: " . $msg . "\n\n"; } } /** * If there still was a connection alive, disconnect it */ public function __destruct() { $this->disconnect(); } }
structNum.php // Class Dictionary
<?php/** * Created by PhpStorm. * User: Administrator * Date: 2018/3/26 * Time: 17:54 */$structNum = array( 46=>new \login\ReqCheckVerifyVerLoginClient(), 47=>new \login\AnsCheckVerifyVerLoginClient(), );
vi use_login.php
<?php/** * Created by PhpStorm. * User: Administrator * Date: 2018/3/26 * Time: 15:20 */require_once 'DrSlump/Protobuf.php'; \DrSlump\Protobuf::autoload();require 'login.php';require 'function.php';//实例化 class 46$login = StructNum(46); $login->setGame(3); $login->setVersion('0.0.1'); $first_data = pack("I*",24063);//一个可识别的ID $first_len = pack("I*",4); $second_data = $login->serialize();//序列化 $second_len = pack("I*",strlen($second_data) + 2); $second_num = substr(pack("I*",46),0,2); $first_pack = $first_len.$first_data; //字节 包体 $second_pack = $second_len.$second_num.$second_data;//长度 协议 内容(protobuf) $port = 9301; $ip = "192.168.128.198"; $pack = array($first_pack,$second_pack); $result = socket($ip,$port,$pack);//连接 发送 接受数据 数据为长度 协议 内容(protobuf) $unPackDatas = unPackData($result);//拆分数据(按需拆分) 按 4 2 2 拆分//实例化 class 46$reLogin = StructNum($unPackDatas['num'][1]); $reLogin->parse($unPackDatas['data']);//拆分后的内容 再反序列化 $reLogin->getRetCode(); $reLogin->getForbidFlag(); $reLogin->clearTimeDiff(); var_dump($reLogin);
Related recommendations:
Detailed explanation of socket communication in php
PHP Socket server construction and test example sharing
Simple method of using Socket in PHP
The above is the detailed content of How to use protobuf-php and socket. For more information, please follow other related articles on the PHP Chinese website!