tcp_client.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2016/10/15
  6. * Time: 下午3:52
  7. */
  8. namespace search;
  9. use Log;
  10. use scope_trace;
  11. abstract class tcp_client
  12. {
  13. const time_out = 3600;
  14. const body_header_len = 10;
  15. //协议打包格式,PHP序列化用于PHP进程间通信,json 格式用于PHP与C++进程间通信
  16. const SerializeType = 1;
  17. const JsonType = 2;
  18. private $mSocket;
  19. protected $mBodyType;
  20. private $mAutoConnect;
  21. protected function __construct($socket = false,$auto_connect = true)
  22. {
  23. $this->mSocket = $socket;
  24. $this->mAutoConnect = $auto_connect;
  25. }
  26. public function __destruct()
  27. {
  28. $this->fini_socket();
  29. }
  30. protected function request($param)
  31. {
  32. $times = 0;
  33. do
  34. {
  35. if($this->init_socket() == false) {
  36. return false;
  37. }
  38. $ret = $this->write_param($param);
  39. if($ret === false) {
  40. $this->fini_socket();
  41. }
  42. }
  43. while($ret == false && ++$times < 2);
  44. if($ret == true)
  45. {
  46. $body = $this->read_body();
  47. if($body != false)
  48. {
  49. if($this->mBodyType == tcp_client::SerializeType) {
  50. return unserialize($body);
  51. } else {
  52. return json_decode($body,true);
  53. }
  54. }
  55. }
  56. else
  57. {
  58. $this->fini_socket();
  59. return false;
  60. }
  61. }
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. private function init_socket()
  64. {
  65. if(!$this->mAutoConnect) return true;
  66. if($this->mSocket != false)
  67. {
  68. if(feof($this->mSocket) == true) {
  69. $this->fini_socket();
  70. } else {
  71. return true;
  72. }
  73. }
  74. $host = $this->remote_addr();
  75. $this->mSocket = @stream_socket_client ($host,$err,$errno,30);
  76. if($this->mSocket == false) {
  77. Log::record("connect server err host:{$host} code:{$errno} : {$err}");
  78. return false;
  79. } else {
  80. Log::record("connect server succ host:{$host} code:{$errno} : {$err}");
  81. socket_set_timeout($this->mSocket,self::time_out);
  82. return true;
  83. }
  84. }
  85. private function fini_socket()
  86. {
  87. if(!$this->mAutoConnect) return;
  88. if($this->mSocket != false) {
  89. Log::record("tcp_client fini_socket",Log::DEBUG);
  90. stream_socket_shutdown($this->mSocket,STREAM_SHUT_RDWR);
  91. fclose($this->mSocket);
  92. $this->mSocket = false;
  93. }
  94. }
  95. private function read_body()
  96. {
  97. do {
  98. $header = $this->read(self::body_header_len);
  99. if($header === false) return false;
  100. $body_len = intval($header);
  101. }
  102. while($body_len === 0);
  103. if($body_len > 0) {
  104. $body = $this->read($body_len);
  105. return $body;
  106. } else {
  107. return false;
  108. }
  109. }
  110. private function read($len)
  111. {
  112. $left = $len;
  113. $data = "";
  114. while ($left > 0)
  115. {
  116. if($this->mAutoConnect)
  117. {
  118. if (feof($this->mSocket) == true) {
  119. return false;
  120. } else {
  121. $tmp = fread($this->mSocket, $left);
  122. }
  123. }
  124. else {
  125. $tmp = @socket_read($this->mSocket,$left);
  126. if(strlen($tmp) == 0) return false;
  127. }
  128. $left = $left - strlen($tmp);
  129. $data .= $tmp;
  130. }
  131. return $data;
  132. }
  133. private function write($data,$len)
  134. {
  135. while ($len > 0)
  136. {
  137. if($this->mAutoConnect) {
  138. $ret = fwrite($this->mSocket,$data);
  139. } else {
  140. $ret = @socket_write($this->mSocket,$data);
  141. }
  142. if($ret == false || $ret <= 0) {
  143. return false;
  144. }
  145. else {
  146. $len -= $ret;
  147. $count = strlen($data);
  148. $data = substr($data,$ret,$count - $ret);
  149. }
  150. }
  151. return true;
  152. }
  153. private function write_param($param)
  154. {
  155. if($this->mBodyType == tcp_client::SerializeType) {
  156. $param = serialize($param);
  157. }
  158. else {
  159. $param = json_encode($param);
  160. }
  161. $len = sprintf("%010d",strlen($param));
  162. $data = $len . $param;
  163. return $this->write($data,strlen($data));
  164. }
  165. abstract function remote_addr();
  166. }
  167. class search_client extends tcp_client
  168. {
  169. const GetRelatedWord = 1;
  170. const SearchReasult = 2;
  171. const MatchPrice = 3;
  172. const PromoteGoods = 4;
  173. const ValidateArea = 20;
  174. protected static $stInstance;
  175. public function __construct()
  176. {
  177. parent::__construct();
  178. $this->mBodyType = tcp_client::SerializeType;
  179. }
  180. public function __destruct()
  181. {
  182. parent::__destruct();
  183. }
  184. public static function instance()
  185. {
  186. if(self::$stInstance == null) {
  187. self::$stInstance = new search_client();
  188. }
  189. return self::$stInstance;
  190. }
  191. public function get_words($word)
  192. {
  193. $param = array("type" => self::GetRelatedWord, "keyword" => $word);
  194. return $this->request($param);
  195. }
  196. public function get_result($params)
  197. {
  198. $param = array("type" => self::SearchReasult, "params" => $params);
  199. return $this->request($param);
  200. }
  201. public function match_price($params)
  202. {
  203. $param = array("type" => self::MatchPrice, "params" => $params);
  204. return $this->request($param);
  205. }
  206. public function promote_goods($params)
  207. {
  208. $param = array("type" => self::PromoteGoods, "params" => $params);
  209. return $this->request($param);
  210. }
  211. public function get_area($area_id)
  212. {
  213. $param = array("type" => self::ValidateArea, "params" => array('area_id' => $area_id));
  214. return $this->request($param);
  215. }
  216. public function remote_addr()
  217. {
  218. global $config;
  219. $host = $config['searcher']['host'];
  220. $port = $config['searcher']['port'];
  221. return "tcp://{$host}:{$port}";
  222. }
  223. }
  224. class relation_client extends tcp_client
  225. {
  226. const GetRelatedWord = 1;
  227. const SearchReasult = 2;
  228. const MatchPrice = 3;
  229. protected static $stInstance;
  230. public function __construct()
  231. {
  232. parent::__construct();
  233. $this->mBodyType = tcp_client::JsonType;
  234. }
  235. public static function instance()
  236. {
  237. if(self::$stInstance == null) {
  238. self::$stInstance = new relation_client();
  239. }
  240. return self::$stInstance;
  241. }
  242. public function __destruct()
  243. {
  244. parent::__destruct();
  245. }
  246. public function remote_addr()
  247. {
  248. global $config;
  249. $host = $config['relation']['host'];
  250. $port = $config['relation']['port'];
  251. return "tcp://{$host}:{$port}";
  252. }
  253. public function add_inviter($param)
  254. {
  255. $param = ["act" => 'inviter','op' => 'add', "params" => $param];
  256. $result = $this->request($param);
  257. if(empty($result)) return false;
  258. $code = intval($result['code']);
  259. if($code != 200) {
  260. return false;
  261. }
  262. else {
  263. return true;
  264. }
  265. }
  266. public function fetch_inviters($param)
  267. {
  268. $param = ["act" => 'inviter','op' => 'list', "params" => $param];
  269. $result = $this->request($param);
  270. $code = intval($result['code']);
  271. if($code != 200) {
  272. return false;
  273. }
  274. else {
  275. return $result['data']['inviters'];
  276. }
  277. }
  278. public function fetch_invitees($param)
  279. {
  280. $param = ["act" => 'inviter','op' => 'invitees', "params" => $param];
  281. $result = $this->request($param);
  282. $code = intval($result['code']);
  283. if($code != 200) {
  284. return false;
  285. }
  286. else {
  287. return $result['data']['invitees'];
  288. }
  289. }
  290. /////////////////////////////////////////////////////////////////////////
  291. public function add_follow($param)
  292. {
  293. $param = ["act" => 'follow','op' => 'add', "params" => $param];
  294. $result = $this->request($param);
  295. if(empty($result)) return false;
  296. $code = intval($result['code']);
  297. if($code != 200) {
  298. return false;
  299. }
  300. else {
  301. return true;
  302. }
  303. }
  304. public function del_follow($param)
  305. {
  306. $param = ["act" => 'follow','op' => 'del', "params" => $param];
  307. $result = $this->request($param);
  308. if(empty($result)) return false;
  309. $code = intval($result['code']);
  310. if($code != 200) {
  311. return false;
  312. }
  313. else {
  314. return true;
  315. }
  316. }
  317. public function fetch_follow($param)
  318. {
  319. $param = ["act" => 'follow','op' => 'fetch', "params" => $param];
  320. $result = $this->request($param);
  321. $code = intval($result['code']);
  322. if($code != 200) {
  323. return false;
  324. }
  325. else {
  326. return $result['data']['follows'];
  327. }
  328. }
  329. public function add_special($param)
  330. {
  331. $param = ["act" => 'special','op' => 'add', "params" => $param];
  332. $result = $this->request($param);
  333. if(empty($result)) return false;
  334. $code = intval($result['code']);
  335. if($code != 200) {
  336. return false;
  337. }
  338. else {
  339. return true;
  340. }
  341. }
  342. public function del_special($param)
  343. {
  344. $param = ["act" => 'special','op' => 'del', "params" => $param];
  345. $result = $this->request($param);
  346. if(empty($result)) return false;
  347. $code = intval($result['code']);
  348. if($code != 200) {
  349. return false;
  350. }
  351. else {
  352. return true;
  353. }
  354. }
  355. public function fetch_self_special($param)
  356. {
  357. $param = ["act" => 'special','op' => 'fetch_self', "params" => $param];
  358. $result = $this->request($param);
  359. $code = intval($result['code']);
  360. if($code != 200) {
  361. return false;
  362. }
  363. else {
  364. return $result['data']['specials'];
  365. }
  366. }
  367. public function fetch_pri_special($param)
  368. {
  369. $param = ["act" => 'special','op' => 'fetch_pri', "params" => $param];
  370. $result = $this->request($param);
  371. $code = intval($result['code']);
  372. if($code != 200) {
  373. return false;
  374. }
  375. else {
  376. return $result['data']['specials'];
  377. }
  378. }
  379. public function fetch_pub_special($param)
  380. {
  381. $param = ["act" => 'special','op' => 'fetch_pub', "params" => $param];
  382. $result = $this->request($param);
  383. $code = intval($result['code']);
  384. if($code != 200) {
  385. return false;
  386. }
  387. else {
  388. return $result['data']['specials'];
  389. }
  390. }
  391. }