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