BaseSDKService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. require_once dirname(dirname(__FILE__)).'/util/HttpClient.php';
  3. require_once dirname(dirname(__FILE__)).'/util/ConfigHelper.php';
  4. require_once dirname(dirname(__FILE__)).'/util/LoggerHelper.php';
  5. require_once dirname(dirname(__FILE__)).'/model/DomainInfo.php';
  6. require_once dirname(dirname(__FILE__)).'/constant/StateCode.php';
  7. require_once dirname(dirname(__FILE__)).'/constant/ServiceName.php';
  8. require_once dirname(dirname(__FILE__)).'/constant/SDKVersion.php';
  9. require_once dirname(dirname(__FILE__)).'/service/DomainServerService.php';
  10. /**
  11. * 请求服务端数据组装类
  12. */
  13. class BaseSDKService{
  14. protected static function getSDKServerResponse (array $params, $prefix, $serviceName){
  15. return BaseSDKService::getServerResponse(ConfigHelper::getStrVal("sdkserver.baseUrl"),
  16. ConfigHelper::getStrValWithDefault("sdkserver.baseUrl.port", ServiceName::$SDK_SERVER_PORT),
  17. self::assemblyHyParam(ServiceName::$DOMAINSERVER_REQ_DN,ServiceName::$ACCOUNT_ID),
  18. $params, $prefix, $serviceName, ServiceName::$DOMAINSERVER_REQ_DN);
  19. }
  20. protected static function getSDKGameDataResponse (array $params, $prefix, $serviceName){
  21. return BaseSDKService::getServerResponse(ConfigHelper::getStrVal("sdkgamedata.baseUrl"),
  22. ConfigHelper::getStrValWithDefault("sdkgamedata.baseUrl.port", ServiceName::$SDK_GAMEDATA_PORT),
  23. self::assemblyHyParam(ServiceName::$DOMAINSERVER_GAMEDATA_DN,ServiceName::$ACCOUNT_ID),
  24. $params, $prefix, $serviceName, ServiceName::$DOMAINSERVER_GAMEDATA_DN);
  25. }
  26. protected static function getSDKRealNameResponse(array $params, $prefix, $serviceName){
  27. return BaseSDKService::getServerResponse(ConfigHelper::getStrVal("sdkrealname.baseUrl"),
  28. ConfigHelper::getStrValWithDefault("sdkrealname.baseUrl.port", ServiceName::$SDK_SERVER_PORT),
  29. self::assemblyHyParam(ServiceName::$DOMAINSERVER_REALNAME_DN,ServiceName::$ACCOUNT_ID),
  30. $params, $prefix, $serviceName, ServiceName::$DOMAINSERVER_REALNAME_DN);
  31. }
  32. /**
  33. * 获取SDKServer服务端的响应
  34. * @param array $params
  35. * @param $prefix
  36. * @param $serviceName
  37. * @return StdClass
  38. * @throws SDKException
  39. */
  40. private static function getServerResponse($serverBaseUrl, $serverPort, $domainServerReqBody, array $params, $prefix, $serviceName, $dn){
  41. try {
  42. $domainService = new DomainServerService();
  43. $requestParam = BaseSDKService::assemblyParameters($serviceName,$params);
  44. $requestBody = json_encode($requestParam);//把参数序列化成一个json字符串
  45. $responseBody = false;
  46. $domainCache = array();
  47. $domainSwith = ConfigHelper::getStrVal("sdkserver.domain.swith");
  48. if ($domainSwith == 'on' && $domainService->cacheOpen()) {
  49. $domainCache = $domainService->getDomainByCache($dn);
  50. $domainService->getHyInfoByCache(ServiceName::$ACCOUNT_ID);
  51. }
  52. $refCache = false;
  53. try {
  54. if(!empty($domainCache) && isset($domainCache['ipAddress']) && !empty($domainCache['ipAddress'])){
  55. LoggerHelper::info("智能域名解析系统缓存存在,直接使用智能域名解析系统返回的IP".json_encode($domainCache['ipAddress'])."访问服务端.");
  56. $responseBody = self::loopPost($domainCache['ipAddress'], $serverPort, $prefix , $serviceName, $requestBody);
  57. $refCache = true;
  58. }else{
  59. $responseBody = HttpClient::quickPost(BaseSDKService::assemblyUrl($serverBaseUrl, $serverPort, $prefix , $serviceName), $requestBody);
  60. }
  61. }catch (Exception $e) {
  62. $responseBody = false;
  63. }
  64. $responseObj = json_decode($responseBody, true);
  65. if ($domainSwith == 'on' && !is_array($responseObj)) {
  66. $domainInfo = $domainService->getDomainByServer(ServiceName::$ACCOUNT_ID, $dn, $domainServerReqBody, $refCache);
  67. if($domainInfo == null){
  68. LoggerHelper::info("请求常规接口".BaseSDKService::assemblyUrl($serverBaseUrl, $serverPort, $prefix , $serviceName)."失败,请求智能域名解析也失败.");
  69. throw new SDKException("请求接口失败");
  70. }
  71. $responseBody = self::loopPost($domainInfo['ipAddress'], $serverPort, $prefix , $serviceName, $requestBody);
  72. $responseObj = json_decode($responseBody, true);
  73. }
  74. if (isset($responseObj["state"]["code"]) && $responseObj["state"]["code"] != StateCode::$SUCCESS) {
  75. //接口返回失败,以异常的形式抛出
  76. LoggerHelper::info("请求接口状态码不为成功.".$responseBody);
  77. throw new SDKException($responseObj["state"]["msg"], $responseObj["state"]["code"]);
  78. }
  79. if (isset($responseObj["data"])) {
  80. return $responseObj["data"];
  81. } else {
  82. LoggerHelper::info("接口数据返回异常!");
  83. throw new SDKException("接口数据返回异常!", 99);
  84. }
  85. } catch (Exception $e) {
  86. if($e instanceof SDKException){
  87. throw $e;
  88. }
  89. LoggerHelper::info("请求接口调用出错.".$e->getMessage());
  90. throw new SDKException($e->getMessage(), -1);
  91. }
  92. }
  93. /**
  94. * 获取毫秒级的时间参数
  95. *
  96. */
  97. private static function getMillisecond() {
  98. $time = explode ( " ", microtime () );
  99. $time = $time [1] . ($time [0] * 1000);
  100. $time2 = explode ( ".", $time );
  101. $time = $time2 [0];
  102. return $time;
  103. }
  104. /**
  105. * 按字母排序$params数组d的键,返回键.值的加密内容
  106. * @param $data 业务数据
  107. */
  108. public static function getSignData(array $params){
  109. ksort($params);
  110. $enData = '';
  111. foreach( $params as $key=>$val ){
  112. $enData = $enData.$key.'='.$val;
  113. }
  114. return $enData;
  115. }
  116. /**
  117. * 按字母排序$params数组d的键,返回键.值的加密内容
  118. * @param $data 业务数据
  119. */
  120. public static function getSignDataWithoutNotInKey(array $params, array $notInKey){
  121. ksort($params);
  122. $enData = '';
  123. foreach( $params as $key=>$val ){
  124. if(in_array($key, $notInKey)){
  125. continue;
  126. }
  127. $enData = $enData.$key.'='.$val;
  128. }
  129. return $enData;
  130. }
  131. /**
  132. * 封装访问入参数据
  133. * @param $serviceName
  134. * @param array $params
  135. * @return array
  136. */
  137. private static function assemblyParameters($serviceName,array $params){
  138. /////////////////组装游戏参数-开始/////////////////////
  139. $gameParam = array();
  140. //gameid是在游戏接入时由UC平台分配
  141. $gameParam["gameId"] = ConfigHelper::getIntVal("sdkserver.game.gameId");
  142. //////////////////组装游戏参数-结束////////////////////
  143. /*
  144. 签名规则=签名内容.apiKey
  145. 假定apiKey=202cb962234w4ers2aaa,sid=abcdefg123456
  146. 那么签名原文sid=abcdefg123456202cb962234w4ers2aaa
  147. 签名结果6e9c3c1e7d99293dfc0c81442f9a9984
  148. */
  149. $signSource = BaseSDKService::getSignData($params).ConfigHelper::getStrVal("sdkserver.game.apikey");//组装签名原文
  150. $sign = md5($signSource);//MD5加密签名
  151. $ex = array();
  152. $ex["ex"] = "language:".SDKVersion::$LANGUAGE ."|version:".SDKVersion::$VERSION;
  153. ///////////////////组装请求参数-开始////////////////////
  154. $requestParam = array();
  155. $requestParam["id"] = BaseSDKService::getMillisecond();//当前系统时间(毫秒)
  156. $requestParam["service"] = $serviceName ;//"account.verifySession";
  157. $requestParam["game"] = $gameParam;
  158. $requestParam["client"] = $ex;
  159. if(count($params) == 0){
  160. $requestParam["data"] = new stdClass();
  161. }else{
  162. $requestParam["data"] = $params;
  163. }
  164. $requestParam["encrypt"] = "md5";
  165. $requestParam["sign"] = $sign;
  166. ///////////////////组装请求参数-结束/////////////////////
  167. return $requestParam;
  168. }
  169. private static function assemblyUrl($sdkServerBaseUrl, $serverPort, $prefix, $serviceName){
  170. return $sdkServerBaseUrl.":".$serverPort."/".$prefix.$serviceName;
  171. }
  172. private static function assemblyHyParam($dn, $accountId) {
  173. $valid = strtolower(md5($dn."aligame"));
  174. return "dn=".$dn."&accountId=".$accountId."&valid=".$valid;
  175. }
  176. private static function loopPost($ips, $serverPort, $prefix , $serviceName, $data) {
  177. if (empty($ips) || !is_array($ips)) {
  178. return false;
  179. }
  180. $i = 1;
  181. $begin = time();
  182. $content = array();
  183. foreach ($ips as $ip) {
  184. $url = self::assemblyUrl("http://".$ip, $serverPort, $prefix , $serviceName);
  185. $content = json_decode(self::curlPost($url, $data, 3),true);
  186. if (!empty($content) && is_array($content)) {
  187. LoggerHelper::info("请求成功,地址:".$url."。data:".$data."。return:".json_encode($content));
  188. break;
  189. } else {
  190. LoggerHelper::info("请求失败,地址:".$url."。data:".$data."。return:".json_encode($content));
  191. }
  192. if ($i >= 3 || time() - $begin >= 5) {
  193. break;
  194. }
  195. $i++;
  196. }
  197. return json_encode($content);
  198. }
  199. private static function curlPost($url, $data, $timeout) {
  200. $curl = curl_init();
  201. // 设置你需要抓取的URL
  202. curl_setopt($curl, CURLOPT_URL, $url);
  203. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);//设置超时时间
  204. curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);//设置超时时间
  205. curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  206. if (preg_match("/^https:\/\//", $url)) {
  207. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //不对认证证书来源的检查
  208. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true); //从证书中检查SSL加密算法是否存在
  209. }
  210. //设置header
  211. curl_setopt($curl, CURLOPT_HEADER, 0);
  212. //设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
  213. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  214. curl_setopt($curl, CURLOPT_POST, 1);
  215. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  216. // 运行cURL,请求网页
  217. $document = curl_exec($curl);
  218. if (curl_errno($curl)) {
  219. return false;
  220. }
  221. // 关闭URL请求
  222. curl_close($curl);
  223. return $document;
  224. }
  225. }