tcp_client.php 10 KB

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