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