winlin

refine log, donot show error when client gracefully close it

1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013-2014 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_app_client.hpp>  
25 -  
26 -#include <arpa/inet.h>  
27 -#include <stdlib.h>  
28 -  
29 -using namespace std;  
30 -  
31 -#include <srs_kernel_error.hpp>  
32 -#include <srs_kernel_log.hpp>  
33 -#include <srs_protocol_rtmp.hpp>  
34 -#include <srs_protocol_rtmp_stack.hpp>  
35 -#include <srs_core_autofree.hpp>  
36 -#include <srs_app_source.hpp>  
37 -#include <srs_app_server.hpp>  
38 -#include <srs_app_pithy_print.hpp>  
39 -#include <srs_app_config.hpp>  
40 -#include <srs_app_refer.hpp>  
41 -#include <srs_app_hls.hpp>  
42 -#include <srs_app_http.hpp>  
43 -#include <srs_app_bandwidth.hpp>  
44 -#include <srs_app_socket.hpp>  
45 -  
46 -SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)  
47 - : SrsConnection(srs_server, client_stfd)  
48 -{  
49 - ip = NULL;  
50 - req = new SrsRequest();  
51 - res = new SrsResponse();  
52 - skt = new SrsSocket(client_stfd);  
53 - rtmp = new SrsRtmpServer(skt);  
54 - refer = new SrsRefer();  
55 -#ifdef SRS_HTTP_CALLBACK  
56 - http_hooks = new SrsHttpHooks();  
57 -#endif  
58 - bandwidth = new SrsBandwidth();  
59 -  
60 - _srs_config->subscribe(this);  
61 -}  
62 -  
63 -SrsClient::~SrsClient()  
64 -{  
65 - _srs_config->unsubscribe(this);  
66 -  
67 - srs_freepa(ip);  
68 - srs_freep(req);  
69 - srs_freep(res);  
70 - srs_freep(rtmp);  
71 - srs_freep(skt);  
72 - srs_freep(refer);  
73 -#ifdef SRS_HTTP_CALLBACK  
74 - srs_freep(http_hooks);  
75 -#endif  
76 - srs_freep(bandwidth);  
77 -}  
78 -  
79 -// TODO: return detail message when error for client.  
80 -int SrsClient::do_cycle()  
81 -{  
82 - int ret = ERROR_SUCCESS;  
83 -  
84 - if ((ret = get_peer_ip()) != ERROR_SUCCESS) {  
85 - srs_error("get peer ip failed. ret=%d", ret);  
86 - return ret;  
87 - }  
88 - srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"",  
89 - ip, SRS_SEND_TIMEOUT_US, SRS_RECV_TIMEOUT_US);  
90 -  
91 - rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);  
92 - rtmp->set_send_timeout(SRS_SEND_TIMEOUT_US);  
93 -  
94 - if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {  
95 - srs_error("rtmp handshake failed. ret=%d", ret);  
96 - return ret;  
97 - }  
98 - srs_verbose("rtmp handshake success");  
99 -  
100 - if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) {  
101 - srs_error("rtmp connect vhost/app failed. ret=%d", ret);  
102 - return ret;  
103 - }  
104 - srs_verbose("rtmp connect app success");  
105 -  
106 - // discovery vhost, resolve the vhost from config  
107 - SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost);  
108 - if (parsed_vhost) {  
109 - req->vhost = parsed_vhost->arg0();  
110 - }  
111 -  
112 - srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",  
113 - req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str());  
114 -  
115 - if (req->schema.empty() || req->vhost.empty() || req->port.empty() || req->app.empty()) {  
116 - ret = ERROR_RTMP_REQ_TCURL;  
117 - srs_error("discovery tcUrl failed. "  
118 - "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",  
119 - req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str(), ret);  
120 - return ret;  
121 - }  
122 -  
123 - // check vhost  
124 - if ((ret = check_vhost()) != ERROR_SUCCESS) {  
125 - srs_error("check vhost failed. ret=%d", ret);  
126 - return ret;  
127 - }  
128 - srs_verbose("check vhost success.");  
129 -  
130 - srs_trace("rtmp connect app success. "  
131 - "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%s, app=%s",  
132 - req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),  
133 - req->schema.c_str(), req->vhost.c_str(), req->port.c_str(),  
134 - req->app.c_str());  
135 -  
136 - ret = service_cycle();  
137 - on_close();  
138 -  
139 - return ret;  
140 -}  
141 -  
142 -int SrsClient::on_reload_vhost_removed(string vhost)  
143 -{  
144 - int ret = ERROR_SUCCESS;  
145 -  
146 - if (req->vhost != vhost) {  
147 - return ret;  
148 - }  
149 -  
150 - // if the vhost connected is removed, disconnect the client.  
151 - srs_trace("vhost %s removed/disabled, close client url=%s",  
152 - vhost.c_str(), req->get_stream_url().c_str());  
153 -  
154 - srs_close_stfd(stfd);  
155 -  
156 - return ret;  
157 -}  
158 -  
159 -int SrsClient::service_cycle()  
160 -{  
161 - int ret = ERROR_SUCCESS;  
162 -  
163 - if ((ret = rtmp->set_window_ack_size(2.5 * 1000 * 1000)) != ERROR_SUCCESS) {  
164 - srs_error("set window acknowledgement size failed. ret=%d", ret);  
165 - return ret;  
166 - }  
167 - srs_verbose("set window acknowledgement size success");  
168 -  
169 - if ((ret = rtmp->set_peer_bandwidth(2.5 * 1000 * 1000, 2)) != ERROR_SUCCESS) {  
170 - srs_error("set peer bandwidth failed. ret=%d", ret);  
171 - return ret;  
172 - }  
173 - srs_verbose("set peer bandwidth success");  
174 -  
175 - // do bandwidth test if connect to the vhost which is for bandwidth check.  
176 - if (_srs_config->get_bw_check_enabled(req->vhost)) {  
177 - return bandwidth->bandwidth_test(req, stfd, rtmp);  
178 - }  
179 -  
180 - if ((ret = rtmp->response_connect_app(req)) != ERROR_SUCCESS) {  
181 - srs_error("response connect app failed. ret=%d", ret);  
182 - return ret;  
183 - }  
184 - srs_verbose("response connect app success");  
185 -  
186 - if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) {  
187 - srs_error("on_bw_done failed. ret=%d", ret);  
188 - return ret;  
189 - }  
190 - srs_verbose("on_bw_done success");  
191 -  
192 - while (true) {  
193 - ret = stream_service_cycle();  
194 -  
195 - // stream service must terminated with error, never success.  
196 - srs_assert(ret != ERROR_SUCCESS);  
197 -  
198 - // when not system control error, fatal error, return.  
199 - if (!srs_is_system_control_error(ret)) {  
200 - if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {  
201 - srs_error("stream service cycle failed. ret=%d", ret);  
202 - }  
203 - return ret;  
204 - }  
205 -  
206 - // for republish, continue service  
207 - if (ret == ERROR_CONTROL_REPUBLISH) {  
208 - // set timeout to a larger value, wait for encoder to republish.  
209 - rtmp->set_send_timeout(SRS_REPUBLISH_RECV_TIMEOUT_US);  
210 - rtmp->set_recv_timeout(SRS_REPUBLISH_SEND_TIMEOUT_US);  
211 -  
212 - srs_trace("control message(unpublish) accept, retry stream service.");  
213 - continue;  
214 - }  
215 -  
216 - // for "some" system control error,  
217 - // logical accept and retry stream service.  
218 - if (ret == ERROR_CONTROL_RTMP_CLOSE) {  
219 - // set timeout to a larger value, for user paused.  
220 - rtmp->set_recv_timeout(SRS_PAUSED_RECV_TIMEOUT_US);  
221 - rtmp->set_send_timeout(SRS_PAUSED_SEND_TIMEOUT_US);  
222 -  
223 - srs_trace("control message(close) accept, retry stream service.");  
224 - continue;  
225 - }  
226 -  
227 - // for other system control message, fatal error.  
228 - srs_error("control message(%d) reject as error. ret=%d", ret, ret);  
229 - return ret;  
230 - }  
231 -  
232 - return ret;  
233 -}  
234 -  
235 -int SrsClient::stream_service_cycle()  
236 -{  
237 - int ret = ERROR_SUCCESS;  
238 -  
239 - SrsClientType type;  
240 - if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {  
241 - srs_error("identify client failed. ret=%d", ret);  
242 - return ret;  
243 - }  
244 - req->strip();  
245 - srs_trace("identify client success. type=%s, stream_name=%s",  
246 - srs_client_type_string(type).c_str(), req->stream.c_str());  
247 -  
248 - // client is identified, set the timeout to service timeout.  
249 - rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);  
250 - rtmp->set_send_timeout(SRS_SEND_TIMEOUT_US);  
251 -  
252 - // set chunk size to larger.  
253 - int chunk_size = _srs_config->get_chunk_size(req->vhost);  
254 - if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) {  
255 - srs_error("set chunk_size=%d failed. ret=%d", chunk_size, ret);  
256 - return ret;  
257 - }  
258 - srs_trace("set chunk_size=%d success", chunk_size);  
259 -  
260 - // find a source to serve.  
261 - SrsSource* source = SrsSource::find(req);  
262 - srs_assert(source != NULL);  
263 -  
264 - // check publish available.  
265 - if (type != SrsClientPlay && !source->can_publish()) {  
266 - ret = ERROR_SYSTEM_STREAM_BUSY;  
267 - srs_warn("stream %s is already publishing. ret=%d",  
268 - req->get_stream_url().c_str(), ret);  
269 - // to delay request  
270 - st_usleep(SRS_STREAM_BUSY_SLEEP_US);  
271 - return ret;  
272 - }  
273 -  
274 - bool enabled_cache = _srs_config->get_gop_cache(req->vhost);  
275 - srs_info("source found, url=%s, enabled_cache=%d", req->get_stream_url().c_str(), enabled_cache);  
276 - source->set_cache(enabled_cache);  
277 -  
278 - switch (type) {  
279 - case SrsClientPlay: {  
280 - srs_verbose("start to play stream %s.", req->stream.c_str());  
281 -  
282 - if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) {  
283 - srs_error("start to play stream failed. ret=%d", ret);  
284 - return ret;  
285 - }  
286 - if ((ret = on_play()) != ERROR_SUCCESS) {  
287 - srs_error("http hook on_play failed. ret=%d", ret);  
288 - return ret;  
289 - }  
290 - srs_info("start to play stream %s success", req->stream.c_str());  
291 - ret = playing(source);  
292 - on_stop();  
293 - return ret;  
294 - }  
295 - case SrsClientFMLEPublish: {  
296 - srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());  
297 -  
298 - if ((ret = rtmp->start_fmle_publish(res->stream_id)) != ERROR_SUCCESS) {  
299 - srs_error("start to publish stream failed. ret=%d", ret);  
300 - return ret;  
301 - }  
302 - if ((ret = on_publish()) != ERROR_SUCCESS) {  
303 - srs_error("http hook on_publish failed. ret=%d", ret);  
304 - return ret;  
305 - }  
306 - srs_info("start to publish stream %s success", req->stream.c_str());  
307 - ret = fmle_publish(source);  
308 - source->on_unpublish();  
309 - on_unpublish();  
310 - return ret;  
311 - }  
312 - case SrsClientFlashPublish: {  
313 - srs_verbose("flash start to publish stream %s.", req->stream.c_str());  
314 -  
315 - if ((ret = rtmp->start_flash_publish(res->stream_id)) != ERROR_SUCCESS) {  
316 - srs_error("flash start to publish stream failed. ret=%d", ret);  
317 - return ret;  
318 - }  
319 - if ((ret = on_publish()) != ERROR_SUCCESS) {  
320 - srs_error("http hook on_publish failed. ret=%d", ret);  
321 - return ret;  
322 - }  
323 - srs_info("flash start to publish stream %s success", req->stream.c_str());  
324 - ret = flash_publish(source);  
325 - source->on_unpublish();  
326 - on_unpublish();  
327 - return ret;  
328 - }  
329 - default: {  
330 - ret = ERROR_SYSTEM_CLIENT_INVALID;  
331 - srs_info("invalid client type=%d. ret=%d", type, ret);  
332 - return ret;  
333 - }  
334 - }  
335 -  
336 - return ret;  
337 -}  
338 -  
339 -int SrsClient::check_vhost()  
340 -{  
341 - int ret = ERROR_SUCCESS;  
342 -  
343 - srs_assert(req != NULL);  
344 -  
345 - SrsConfDirective* vhost = _srs_config->get_vhost(req->vhost);  
346 - if (vhost == NULL) {  
347 - ret = ERROR_RTMP_VHOST_NOT_FOUND;  
348 - srs_error("vhost %s not found. ret=%d", req->vhost.c_str(), ret);  
349 - return ret;  
350 - }  
351 -  
352 - if (!_srs_config->get_vhost_enabled(req->vhost)) {  
353 - ret = ERROR_RTMP_VHOST_NOT_FOUND;  
354 - srs_error("vhost %s disabled. ret=%d", req->vhost.c_str(), ret);  
355 - return ret;  
356 - }  
357 -  
358 - if (req->vhost != vhost->arg0()) {  
359 - srs_trace("vhost change from %s to %s", req->vhost.c_str(), vhost->arg0().c_str());  
360 - req->vhost = vhost->arg0();  
361 - }  
362 -  
363 - if ((ret = refer->check(req->pageUrl, _srs_config->get_refer(req->vhost))) != ERROR_SUCCESS) {  
364 - srs_error("check refer failed. ret=%d", ret);  
365 - return ret;  
366 - }  
367 - srs_verbose("check refer success.");  
368 -  
369 - if ((ret = on_connect()) != ERROR_SUCCESS) {  
370 - return ret;  
371 - }  
372 -  
373 - return ret;  
374 -}  
375 -  
376 -int SrsClient::playing(SrsSource* source)  
377 -{  
378 - int ret = ERROR_SUCCESS;  
379 -  
380 - if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_play(req->vhost))) != ERROR_SUCCESS) {  
381 - srs_error("check play_refer failed. ret=%d", ret);  
382 - return ret;  
383 - }  
384 - srs_verbose("check play_refer success.");  
385 -  
386 - SrsConsumer* consumer = NULL;  
387 - if ((ret = source->create_consumer(consumer)) != ERROR_SUCCESS) {  
388 - srs_error("create consumer failed. ret=%d", ret);  
389 - return ret;  
390 - }  
391 -  
392 - srs_assert(consumer != NULL);  
393 - SrsAutoFree(SrsConsumer, consumer, false);  
394 - srs_verbose("consumer created success.");  
395 -  
396 - rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US);  
397 -  
398 - SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);  
399 -  
400 - while (true) {  
401 - pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);  
402 -  
403 - // switch to other st-threads.  
404 - st_usleep(0);  
405 -  
406 - // read from client.  
407 - int ctl_msg_ret = ERROR_SUCCESS;  
408 - if (true) {  
409 - SrsCommonMessage* msg = NULL;  
410 - ctl_msg_ret = ret = rtmp->recv_message(&msg);  
411 -  
412 - srs_verbose("play loop recv message. ret=%d", ret);  
413 - if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {  
414 - if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {  
415 - srs_error("recv client control message failed. ret=%d", ret);  
416 - }  
417 - return ret;  
418 - }  
419 - if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {  
420 - if (!srs_is_system_control_error(ret)) {  
421 - srs_error("process play control message failed. ret=%d", ret);  
422 - }  
423 - return ret;  
424 - }  
425 - }  
426 -  
427 - // get messages from consumer.  
428 - SrsSharedPtrMessage** msgs = NULL;  
429 - int count = 0;  
430 - if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) {  
431 - srs_error("get messages from consumer failed. ret=%d", ret);  
432 - return ret;  
433 - }  
434 -  
435 - // reportable  
436 - if (pithy_print.can_print()) {  
437 - srs_trace("-> time=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
438 - pithy_print.get_age(), ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());  
439 - }  
440 -  
441 - if (count <= 0) {  
442 - srs_verbose("no packets in queue.");  
443 - continue;  
444 - }  
445 - SrsAutoFree(SrsSharedPtrMessage*, msgs, true);  
446 -  
447 - // sendout messages  
448 - for (int i = 0; i < count; i++) {  
449 - SrsSharedPtrMessage* msg = msgs[i];  
450 -  
451 - // the send_message will free the msg,  
452 - // so set the msgs[i] to NULL.  
453 - msgs[i] = NULL;  
454 -  
455 - if ((ret = rtmp->send_message(msg)) != ERROR_SUCCESS) {  
456 - srs_error("send message to client failed. ret=%d", ret);  
457 - return ret;  
458 - }  
459 - }  
460 - }  
461 -  
462 - return ret;  
463 -}  
464 -  
465 -int SrsClient::fmle_publish(SrsSource* source)  
466 -{  
467 - int ret = ERROR_SUCCESS;  
468 -  
469 - if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {  
470 - srs_error("fmle check publish_refer failed. ret=%d", ret);  
471 - return ret;  
472 - }  
473 - srs_verbose("fmle check publish_refer success.");  
474 -  
475 - SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);  
476 -  
477 - // notify the hls to prepare when publish start.  
478 - if ((ret = source->on_publish(req)) != ERROR_SUCCESS) {  
479 - srs_error("fmle hls on_publish failed. ret=%d", ret);  
480 - return ret;  
481 - }  
482 - srs_verbose("fmle hls on_publish success.");  
483 -  
484 - while (true) {  
485 - // switch to other st-threads.  
486 - st_usleep(0);  
487 -  
488 - SrsCommonMessage* msg = NULL;  
489 - if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {  
490 - srs_error("fmle recv identify client message failed. ret=%d", ret);  
491 - return ret;  
492 - }  
493 -  
494 - SrsAutoFree(SrsCommonMessage, msg, false);  
495 -  
496 - pithy_print.set_age(msg->header.timestamp);  
497 -  
498 - // reportable  
499 - if (pithy_print.can_print()) {  
500 - srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
501 - pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());  
502 - }  
503 -  
504 - // process UnPublish event.  
505 - if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {  
506 - if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {  
507 - srs_error("fmle decode unpublish message failed. ret=%d", ret);  
508 - return ret;  
509 - }  
510 -  
511 - SrsPacket* pkt = msg->get_packet();  
512 - if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {  
513 - SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);  
514 - if ((ret = rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id)) != ERROR_SUCCESS) {  
515 - return ret;  
516 - }  
517 - return ERROR_CONTROL_REPUBLISH;  
518 - }  
519 -  
520 - srs_trace("fmle ignore AMF0/AMF3 command message.");  
521 - continue;  
522 - }  
523 -  
524 - // video, audio, data message  
525 - if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) {  
526 - srs_error("fmle process publish message failed. ret=%d", ret);  
527 - return ret;  
528 - }  
529 - }  
530 -  
531 - return ret;  
532 -}  
533 -  
534 -int SrsClient::flash_publish(SrsSource* source)  
535 -{  
536 - int ret = ERROR_SUCCESS;  
537 -  
538 - if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {  
539 - srs_error("flash check publish_refer failed. ret=%d", ret);  
540 - return ret;  
541 - }  
542 - srs_verbose("flash check publish_refer success.");  
543 -  
544 - SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);  
545 -  
546 - // notify the hls to prepare when publish start.  
547 - if ((ret = source->on_publish(req)) != ERROR_SUCCESS) {  
548 - srs_error("flash hls on_publish failed. ret=%d", ret);  
549 - return ret;  
550 - }  
551 - srs_verbose("flash hls on_publish success.");  
552 -  
553 - while (true) {  
554 - // switch to other st-threads.  
555 - st_usleep(0);  
556 -  
557 - SrsCommonMessage* msg = NULL;  
558 - if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {  
559 - srs_error("flash recv identify client message failed. ret=%d", ret);  
560 - return ret;  
561 - }  
562 -  
563 - SrsAutoFree(SrsCommonMessage, msg, false);  
564 -  
565 - pithy_print.set_age(msg->header.timestamp);  
566 -  
567 - // reportable  
568 - if (pithy_print.can_print()) {  
569 - srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
570 - pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());  
571 - }  
572 -  
573 - // process UnPublish event.  
574 - if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {  
575 - if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {  
576 - srs_error("flash decode unpublish message failed. ret=%d", ret);  
577 - return ret;  
578 - }  
579 -  
580 - // flash unpublish.  
581 - // TODO: maybe need to support republish.  
582 - srs_trace("flash flash publish finished.");  
583 - return ERROR_CONTROL_REPUBLISH;  
584 - }  
585 -  
586 - // video, audio, data message  
587 - if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) {  
588 - srs_error("flash process publish message failed. ret=%d", ret);  
589 - return ret;  
590 - }  
591 - }  
592 -  
593 - return ret;  
594 -}  
595 -  
596 -int SrsClient::process_publish_message(SrsSource* source, SrsCommonMessage* msg)  
597 -{  
598 - int ret = ERROR_SUCCESS;  
599 -  
600 - // process audio packet  
601 - if (msg->header.is_audio()) {  
602 - if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) {  
603 - srs_error("source process audio message failed. ret=%d", ret);  
604 - return ret;  
605 - }  
606 - }  
607 - // process video packet  
608 - if (msg->header.is_video()) {  
609 - if ((ret = source->on_video(msg)) != ERROR_SUCCESS) {  
610 - srs_error("source process video message failed. ret=%d", ret);  
611 - return ret;  
612 - }  
613 - }  
614 -  
615 - // process onMetaData  
616 - if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {  
617 - if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {  
618 - srs_error("decode onMetaData message failed. ret=%d", ret);  
619 - return ret;  
620 - }  
621 -  
622 - SrsPacket* pkt = msg->get_packet();  
623 - if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {  
624 - SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);  
625 - if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {  
626 - srs_error("source process onMetaData message failed. ret=%d", ret);  
627 - return ret;  
628 - }  
629 - srs_trace("process onMetaData message success.");  
630 - return ret;  
631 - }  
632 -  
633 - srs_trace("ignore AMF0/AMF3 data message.");  
634 - return ret;  
635 - }  
636 -  
637 - return ret;  
638 -}  
639 -  
640 -int SrsClient::get_peer_ip()  
641 -{  
642 - int ret = ERROR_SUCCESS;  
643 -  
644 - int fd = st_netfd_fileno(stfd);  
645 -  
646 - // discovery client information  
647 - sockaddr_in addr;  
648 - socklen_t addrlen = sizeof(addr);  
649 - if (getpeername(fd, (sockaddr*)&addr, &addrlen) == -1) {  
650 - ret = ERROR_SOCKET_GET_PEER_NAME;  
651 - srs_error("discovery client information failed. ret=%d", ret);  
652 - return ret;  
653 - }  
654 - srs_verbose("get peer name success.");  
655 -  
656 - // ip v4 or v6  
657 - char buf[INET6_ADDRSTRLEN];  
658 - memset(buf, 0, sizeof(buf));  
659 -  
660 - if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) {  
661 - ret = ERROR_SOCKET_GET_PEER_IP;  
662 - srs_error("convert client information failed. ret=%d", ret);  
663 - return ret;  
664 - }  
665 - srs_verbose("get peer ip of client ip=%s, fd=%d", buf, fd);  
666 -  
667 - ip = new char[strlen(buf) + 1];  
668 - strcpy(ip, buf);  
669 -  
670 - srs_verbose("get peer ip success. ip=%s, fd=%d", ip, fd);  
671 -  
672 - return ret;  
673 -}  
674 -  
675 -int SrsClient::process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg)  
676 -{  
677 - int ret = ERROR_SUCCESS;  
678 -  
679 - if (!msg) {  
680 - srs_verbose("ignore all empty message.");  
681 - return ret;  
682 - }  
683 - SrsAutoFree(SrsCommonMessage, msg, false);  
684 -  
685 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
686 - srs_info("ignore all message except amf0/amf3 command.");  
687 - return ret;  
688 - }  
689 -  
690 - if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {  
691 - srs_error("decode the amf0/amf3 command packet failed. ret=%d", ret);  
692 - return ret;  
693 - }  
694 - srs_info("decode the amf0/amf3 command packet success.");  
695 -  
696 - SrsCloseStreamPacket* close = dynamic_cast<SrsCloseStreamPacket*>(msg->get_packet());  
697 - if (close) {  
698 - ret = ERROR_CONTROL_RTMP_CLOSE;  
699 - srs_trace("system control message: rtmp close stream. ret=%d", ret);  
700 - return ret;  
701 - }  
702 -  
703 - SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(msg->get_packet());  
704 - if (!pause) {  
705 - srs_info("ignore all amf0/amf3 command except pause.");  
706 - return ret;  
707 - }  
708 -  
709 - if ((ret = rtmp->on_play_client_pause(res->stream_id, pause->is_pause)) != ERROR_SUCCESS) {  
710 - srs_error("rtmp process play client pause failed. ret=%d", ret);  
711 - return ret;  
712 - }  
713 -  
714 - if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) {  
715 - srs_error("consumer process play client pause failed. ret=%d", ret);  
716 - return ret;  
717 - }  
718 - srs_info("process pause success, is_pause=%d, time=%d.", pause->is_pause, pause->time_ms);  
719 -  
720 - return ret;  
721 -}  
722 -  
723 -int SrsClient::on_connect()  
724 -{  
725 - int ret = ERROR_SUCCESS;  
726 -  
727 -#ifdef SRS_HTTP_CALLBACK  
728 - // HTTP: on_connect  
729 - SrsConfDirective* on_connect = _srs_config->get_vhost_on_connect(req->vhost);  
730 - if (!on_connect) {  
731 - srs_info("ignore the empty http callback: on_connect");  
732 - return ret;  
733 - }  
734 -  
735 - for (int i = 0; i < (int)on_connect->args.size(); i++) {  
736 - std::string url = on_connect->args.at(i);  
737 - if ((ret = http_hooks->on_connect(url, connection_id, ip, req)) != ERROR_SUCCESS) {  
738 - srs_error("hook client on_connect failed. url=%s, ret=%d", url.c_str(), ret);  
739 - return ret;  
740 - }  
741 - }  
742 -#endif  
743 -  
744 - return ret;  
745 -}  
746 -  
747 -void SrsClient::on_close()  
748 -{  
749 -#ifdef SRS_HTTP_CALLBACK  
750 - // whatever the ret code, notify the api hooks.  
751 - // HTTP: on_close  
752 - SrsConfDirective* on_close = _srs_config->get_vhost_on_close(req->vhost);  
753 - if (!on_close) {  
754 - srs_info("ignore the empty http callback: on_close");  
755 - return;  
756 - }  
757 -  
758 - for (int i = 0; i < (int)on_close->args.size(); i++) {  
759 - std::string url = on_close->args.at(i);  
760 - http_hooks->on_close(url, connection_id, ip, req);  
761 - }  
762 -#endif  
763 -}  
764 -  
765 -int SrsClient::on_publish()  
766 -{  
767 - int ret = ERROR_SUCCESS;  
768 -  
769 -#ifdef SRS_HTTP_CALLBACK  
770 - // HTTP: on_publish  
771 - SrsConfDirective* on_publish = _srs_config->get_vhost_on_publish(req->vhost);  
772 - if (!on_publish) {  
773 - srs_info("ignore the empty http callback: on_publish");  
774 - return ret;  
775 - }  
776 -  
777 - for (int i = 0; i < (int)on_publish->args.size(); i++) {  
778 - std::string url = on_publish->args.at(i);  
779 - if ((ret = http_hooks->on_publish(url, connection_id, ip, req)) != ERROR_SUCCESS) {  
780 - srs_error("hook client on_publish failed. url=%s, ret=%d", url.c_str(), ret);  
781 - return ret;  
782 - }  
783 - }  
784 -#endif  
785 -  
786 - return ret;  
787 -}  
788 -  
789 -void SrsClient::on_unpublish()  
790 -{  
791 -#ifdef SRS_HTTP_CALLBACK  
792 - // whatever the ret code, notify the api hooks.  
793 - // HTTP: on_unpublish  
794 - SrsConfDirective* on_unpublish = _srs_config->get_vhost_on_unpublish(req->vhost);  
795 - if (!on_unpublish) {  
796 - srs_info("ignore the empty http callback: on_unpublish");  
797 - return;  
798 - }  
799 -  
800 - for (int i = 0; i < (int)on_unpublish->args.size(); i++) {  
801 - std::string url = on_unpublish->args.at(i);  
802 - http_hooks->on_unpublish(url, connection_id, ip, req);  
803 - }  
804 -#endif  
805 -}  
806 -  
807 -int SrsClient::on_play()  
808 -{  
809 - int ret = ERROR_SUCCESS;  
810 -  
811 -#ifdef SRS_HTTP_CALLBACK  
812 - // HTTP: on_play  
813 - SrsConfDirective* on_play = _srs_config->get_vhost_on_play(req->vhost);  
814 - if (!on_play) {  
815 - srs_info("ignore the empty http callback: on_play");  
816 - return ret;  
817 - }  
818 -  
819 - for (int i = 0; i < (int)on_play->args.size(); i++) {  
820 - std::string url = on_play->args.at(i);  
821 - if ((ret = http_hooks->on_play(url, connection_id, ip, req)) != ERROR_SUCCESS) {  
822 - srs_error("hook client on_play failed. url=%s, ret=%d", url.c_str(), ret);  
823 - return ret;  
824 - }  
825 - }  
826 -#endif  
827 -  
828 - return ret;  
829 -}  
830 -  
831 -void SrsClient::on_stop()  
832 -{  
833 -#ifdef SRS_HTTP_CALLBACK  
834 - // whatever the ret code, notify the api hooks.  
835 - // HTTP: on_stop  
836 - SrsConfDirective* on_stop = _srs_config->get_vhost_on_stop(req->vhost);  
837 - if (!on_stop) {  
838 - srs_info("ignore the empty http callback: on_stop");  
839 - return;  
840 - }  
841 -  
842 - for (int i = 0; i < (int)on_stop->args.size(); i++) {  
843 - std::string url = on_stop->args.at(i);  
844 - http_hooks->on_stop(url, connection_id, ip, req);  
845 - }  
846 -#endif  
847 -} 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_app_client.hpp>
  25 +
  26 +#include <arpa/inet.h>
  27 +#include <stdlib.h>
  28 +
  29 +using namespace std;
  30 +
  31 +#include <srs_kernel_error.hpp>
  32 +#include <srs_kernel_log.hpp>
  33 +#include <srs_protocol_rtmp.hpp>
  34 +#include <srs_protocol_rtmp_stack.hpp>
  35 +#include <srs_core_autofree.hpp>
  36 +#include <srs_app_source.hpp>
  37 +#include <srs_app_server.hpp>
  38 +#include <srs_app_pithy_print.hpp>
  39 +#include <srs_app_config.hpp>
  40 +#include <srs_app_refer.hpp>
  41 +#include <srs_app_hls.hpp>
  42 +#include <srs_app_http.hpp>
  43 +#include <srs_app_bandwidth.hpp>
  44 +#include <srs_app_socket.hpp>
  45 +
  46 +SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
  47 + : SrsConnection(srs_server, client_stfd)
  48 +{
  49 + ip = NULL;
  50 + req = new SrsRequest();
  51 + res = new SrsResponse();
  52 + skt = new SrsSocket(client_stfd);
  53 + rtmp = new SrsRtmpServer(skt);
  54 + refer = new SrsRefer();
  55 +#ifdef SRS_HTTP_CALLBACK
  56 + http_hooks = new SrsHttpHooks();
  57 +#endif
  58 + bandwidth = new SrsBandwidth();
  59 +
  60 + _srs_config->subscribe(this);
  61 +}
  62 +
  63 +SrsClient::~SrsClient()
  64 +{
  65 + _srs_config->unsubscribe(this);
  66 +
  67 + srs_freepa(ip);
  68 + srs_freep(req);
  69 + srs_freep(res);
  70 + srs_freep(rtmp);
  71 + srs_freep(skt);
  72 + srs_freep(refer);
  73 +#ifdef SRS_HTTP_CALLBACK
  74 + srs_freep(http_hooks);
  75 +#endif
  76 + srs_freep(bandwidth);
  77 +}
  78 +
  79 +// TODO: return detail message when error for client.
  80 +int SrsClient::do_cycle()
  81 +{
  82 + int ret = ERROR_SUCCESS;
  83 +
  84 + if ((ret = get_peer_ip()) != ERROR_SUCCESS) {
  85 + srs_error("get peer ip failed. ret=%d", ret);
  86 + return ret;
  87 + }
  88 + srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"",
  89 + ip, SRS_SEND_TIMEOUT_US, SRS_RECV_TIMEOUT_US);
  90 +
  91 + rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
  92 + rtmp->set_send_timeout(SRS_SEND_TIMEOUT_US);
  93 +
  94 + if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {
  95 + srs_error("rtmp handshake failed. ret=%d", ret);
  96 + return ret;
  97 + }
  98 + srs_verbose("rtmp handshake success");
  99 +
  100 + if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) {
  101 + srs_error("rtmp connect vhost/app failed. ret=%d", ret);
  102 + return ret;
  103 + }
  104 + srs_verbose("rtmp connect app success");
  105 +
  106 + // discovery vhost, resolve the vhost from config
  107 + SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost);
  108 + if (parsed_vhost) {
  109 + req->vhost = parsed_vhost->arg0();
  110 + }
  111 +
  112 + srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",
  113 + req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str());
  114 +
  115 + if (req->schema.empty() || req->vhost.empty() || req->port.empty() || req->app.empty()) {
  116 + ret = ERROR_RTMP_REQ_TCURL;
  117 + srs_error("discovery tcUrl failed. "
  118 + "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",
  119 + req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str(), ret);
  120 + return ret;
  121 + }
  122 +
  123 + // check vhost
  124 + if ((ret = check_vhost()) != ERROR_SUCCESS) {
  125 + srs_error("check vhost failed. ret=%d", ret);
  126 + return ret;
  127 + }
  128 + srs_verbose("check vhost success.");
  129 +
  130 + srs_trace("rtmp connect app success. "
  131 + "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%s, app=%s",
  132 + req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),
  133 + req->schema.c_str(), req->vhost.c_str(), req->port.c_str(),
  134 + req->app.c_str());
  135 +
  136 + ret = service_cycle();
  137 + on_close();
  138 +
  139 + return ret;
  140 +}
  141 +
  142 +int SrsClient::on_reload_vhost_removed(string vhost)
  143 +{
  144 + int ret = ERROR_SUCCESS;
  145 +
  146 + if (req->vhost != vhost) {
  147 + return ret;
  148 + }
  149 +
  150 + // if the vhost connected is removed, disconnect the client.
  151 + srs_trace("vhost %s removed/disabled, close client url=%s",
  152 + vhost.c_str(), req->get_stream_url().c_str());
  153 +
  154 + srs_close_stfd(stfd);
  155 +
  156 + return ret;
  157 +}
  158 +
  159 +int SrsClient::service_cycle()
  160 +{
  161 + int ret = ERROR_SUCCESS;
  162 +
  163 + if ((ret = rtmp->set_window_ack_size(2.5 * 1000 * 1000)) != ERROR_SUCCESS) {
  164 + srs_error("set window acknowledgement size failed. ret=%d", ret);
  165 + return ret;
  166 + }
  167 + srs_verbose("set window acknowledgement size success");
  168 +
  169 + if ((ret = rtmp->set_peer_bandwidth(2.5 * 1000 * 1000, 2)) != ERROR_SUCCESS) {
  170 + srs_error("set peer bandwidth failed. ret=%d", ret);
  171 + return ret;
  172 + }
  173 + srs_verbose("set peer bandwidth success");
  174 +
  175 + // do bandwidth test if connect to the vhost which is for bandwidth check.
  176 + if (_srs_config->get_bw_check_enabled(req->vhost)) {
  177 + return bandwidth->bandwidth_test(req, stfd, rtmp);
  178 + }
  179 +
  180 + if ((ret = rtmp->response_connect_app(req)) != ERROR_SUCCESS) {
  181 + srs_error("response connect app failed. ret=%d", ret);
  182 + return ret;
  183 + }
  184 + srs_verbose("response connect app success");
  185 +
  186 + if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) {
  187 + srs_error("on_bw_done failed. ret=%d", ret);
  188 + return ret;
  189 + }
  190 + srs_verbose("on_bw_done success");
  191 +
  192 + while (true) {
  193 + ret = stream_service_cycle();
  194 +
  195 + // stream service must terminated with error, never success.
  196 + srs_assert(ret != ERROR_SUCCESS);
  197 +
  198 + // when not system control error, fatal error, return.
  199 + if (!srs_is_system_control_error(ret)) {
  200 + if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {
  201 + srs_error("stream service cycle failed. ret=%d", ret);
  202 + }
  203 + return ret;
  204 + }
  205 +
  206 + // for republish, continue service
  207 + if (ret == ERROR_CONTROL_REPUBLISH) {
  208 + // set timeout to a larger value, wait for encoder to republish.
  209 + rtmp->set_send_timeout(SRS_REPUBLISH_RECV_TIMEOUT_US);
  210 + rtmp->set_recv_timeout(SRS_REPUBLISH_SEND_TIMEOUT_US);
  211 +
  212 + srs_trace("control message(unpublish) accept, retry stream service.");
  213 + continue;
  214 + }
  215 +
  216 + // for "some" system control error,
  217 + // logical accept and retry stream service.
  218 + if (ret == ERROR_CONTROL_RTMP_CLOSE) {
  219 + // set timeout to a larger value, for user paused.
  220 + rtmp->set_recv_timeout(SRS_PAUSED_RECV_TIMEOUT_US);
  221 + rtmp->set_send_timeout(SRS_PAUSED_SEND_TIMEOUT_US);
  222 +
  223 + srs_trace("control message(close) accept, retry stream service.");
  224 + continue;
  225 + }
  226 +
  227 + // for other system control message, fatal error.
  228 + srs_error("control message(%d) reject as error. ret=%d", ret, ret);
  229 + return ret;
  230 + }
  231 +
  232 + return ret;
  233 +}
  234 +
  235 +int SrsClient::stream_service_cycle()
  236 +{
  237 + int ret = ERROR_SUCCESS;
  238 +
  239 + SrsClientType type;
  240 + if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {
  241 + srs_error("identify client failed. ret=%d", ret);
  242 + return ret;
  243 + }
  244 + req->strip();
  245 + srs_trace("identify client success. type=%s, stream_name=%s",
  246 + srs_client_type_string(type).c_str(), req->stream.c_str());
  247 +
  248 + // client is identified, set the timeout to service timeout.
  249 + rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
  250 + rtmp->set_send_timeout(SRS_SEND_TIMEOUT_US);
  251 +
  252 + // set chunk size to larger.
  253 + int chunk_size = _srs_config->get_chunk_size(req->vhost);
  254 + if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) {
  255 + srs_error("set chunk_size=%d failed. ret=%d", chunk_size, ret);
  256 + return ret;
  257 + }
  258 + srs_trace("set chunk_size=%d success", chunk_size);
  259 +
  260 + // find a source to serve.
  261 + SrsSource* source = SrsSource::find(req);
  262 + srs_assert(source != NULL);
  263 +
  264 + // check publish available.
  265 + if (type != SrsClientPlay && !source->can_publish()) {
  266 + ret = ERROR_SYSTEM_STREAM_BUSY;
  267 + srs_warn("stream %s is already publishing. ret=%d",
  268 + req->get_stream_url().c_str(), ret);
  269 + // to delay request
  270 + st_usleep(SRS_STREAM_BUSY_SLEEP_US);
  271 + return ret;
  272 + }
  273 +
  274 + bool enabled_cache = _srs_config->get_gop_cache(req->vhost);
  275 + srs_info("source found, url=%s, enabled_cache=%d", req->get_stream_url().c_str(), enabled_cache);
  276 + source->set_cache(enabled_cache);
  277 +
  278 + switch (type) {
  279 + case SrsClientPlay: {
  280 + srs_verbose("start to play stream %s.", req->stream.c_str());
  281 +
  282 + if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) {
  283 + srs_error("start to play stream failed. ret=%d", ret);
  284 + return ret;
  285 + }
  286 + if ((ret = on_play()) != ERROR_SUCCESS) {
  287 + srs_error("http hook on_play failed. ret=%d", ret);
  288 + return ret;
  289 + }
  290 + srs_info("start to play stream %s success", req->stream.c_str());
  291 + ret = playing(source);
  292 + on_stop();
  293 + return ret;
  294 + }
  295 + case SrsClientFMLEPublish: {
  296 + srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());
  297 +
  298 + if ((ret = rtmp->start_fmle_publish(res->stream_id)) != ERROR_SUCCESS) {
  299 + srs_error("start to publish stream failed. ret=%d", ret);
  300 + return ret;
  301 + }
  302 + if ((ret = on_publish()) != ERROR_SUCCESS) {
  303 + srs_error("http hook on_publish failed. ret=%d", ret);
  304 + return ret;
  305 + }
  306 + srs_info("start to publish stream %s success", req->stream.c_str());
  307 + ret = fmle_publish(source);
  308 + source->on_unpublish();
  309 + on_unpublish();
  310 + return ret;
  311 + }
  312 + case SrsClientFlashPublish: {
  313 + srs_verbose("flash start to publish stream %s.", req->stream.c_str());
  314 +
  315 + if ((ret = rtmp->start_flash_publish(res->stream_id)) != ERROR_SUCCESS) {
  316 + srs_error("flash start to publish stream failed. ret=%d", ret);
  317 + return ret;
  318 + }
  319 + if ((ret = on_publish()) != ERROR_SUCCESS) {
  320 + srs_error("http hook on_publish failed. ret=%d", ret);
  321 + return ret;
  322 + }
  323 + srs_info("flash start to publish stream %s success", req->stream.c_str());
  324 + ret = flash_publish(source);
  325 + source->on_unpublish();
  326 + on_unpublish();
  327 + return ret;
  328 + }
  329 + default: {
  330 + ret = ERROR_SYSTEM_CLIENT_INVALID;
  331 + srs_info("invalid client type=%d. ret=%d", type, ret);
  332 + return ret;
  333 + }
  334 + }
  335 +
  336 + return ret;
  337 +}
  338 +
  339 +int SrsClient::check_vhost()
  340 +{
  341 + int ret = ERROR_SUCCESS;
  342 +
  343 + srs_assert(req != NULL);
  344 +
  345 + SrsConfDirective* vhost = _srs_config->get_vhost(req->vhost);
  346 + if (vhost == NULL) {
  347 + ret = ERROR_RTMP_VHOST_NOT_FOUND;
  348 + srs_error("vhost %s not found. ret=%d", req->vhost.c_str(), ret);
  349 + return ret;
  350 + }
  351 +
  352 + if (!_srs_config->get_vhost_enabled(req->vhost)) {
  353 + ret = ERROR_RTMP_VHOST_NOT_FOUND;
  354 + srs_error("vhost %s disabled. ret=%d", req->vhost.c_str(), ret);
  355 + return ret;
  356 + }
  357 +
  358 + if (req->vhost != vhost->arg0()) {
  359 + srs_trace("vhost change from %s to %s", req->vhost.c_str(), vhost->arg0().c_str());
  360 + req->vhost = vhost->arg0();
  361 + }
  362 +
  363 + if ((ret = refer->check(req->pageUrl, _srs_config->get_refer(req->vhost))) != ERROR_SUCCESS) {
  364 + srs_error("check refer failed. ret=%d", ret);
  365 + return ret;
  366 + }
  367 + srs_verbose("check refer success.");
  368 +
  369 + if ((ret = on_connect()) != ERROR_SUCCESS) {
  370 + return ret;
  371 + }
  372 +
  373 + return ret;
  374 +}
  375 +
  376 +int SrsClient::playing(SrsSource* source)
  377 +{
  378 + int ret = ERROR_SUCCESS;
  379 +
  380 + if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_play(req->vhost))) != ERROR_SUCCESS) {
  381 + srs_error("check play_refer failed. ret=%d", ret);
  382 + return ret;
  383 + }
  384 + srs_verbose("check play_refer success.");
  385 +
  386 + SrsConsumer* consumer = NULL;
  387 + if ((ret = source->create_consumer(consumer)) != ERROR_SUCCESS) {
  388 + srs_error("create consumer failed. ret=%d", ret);
  389 + return ret;
  390 + }
  391 +
  392 + srs_assert(consumer != NULL);
  393 + SrsAutoFree(SrsConsumer, consumer, false);
  394 + srs_verbose("consumer created success.");
  395 +
  396 + rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US);
  397 +
  398 + SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);
  399 +
  400 + while (true) {
  401 + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);
  402 +
  403 + // switch to other st-threads.
  404 + st_usleep(0);
  405 +
  406 + // read from client.
  407 + int ctl_msg_ret = ERROR_SUCCESS;
  408 + if (true) {
  409 + SrsCommonMessage* msg = NULL;
  410 + ctl_msg_ret = ret = rtmp->recv_message(&msg);
  411 +
  412 + srs_verbose("play loop recv message. ret=%d", ret);
  413 + if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {
  414 + if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {
  415 + srs_error("recv client control message failed. ret=%d", ret);
  416 + }
  417 + return ret;
  418 + }
  419 + if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {
  420 + if (!srs_is_system_control_error(ret)) {
  421 + srs_error("process play control message failed. ret=%d", ret);
  422 + }
  423 + return ret;
  424 + }
  425 + }
  426 +
  427 + // get messages from consumer.
  428 + SrsSharedPtrMessage** msgs = NULL;
  429 + int count = 0;
  430 + if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) {
  431 + srs_error("get messages from consumer failed. ret=%d", ret);
  432 + return ret;
  433 + }
  434 +
  435 + // reportable
  436 + if (pithy_print.can_print()) {
  437 + srs_trace("-> time=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  438 + pithy_print.get_age(), ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  439 + }
  440 +
  441 + if (count <= 0) {
  442 + srs_verbose("no packets in queue.");
  443 + continue;
  444 + }
  445 + SrsAutoFree(SrsSharedPtrMessage*, msgs, true);
  446 +
  447 + // sendout messages
  448 + for (int i = 0; i < count; i++) {
  449 + SrsSharedPtrMessage* msg = msgs[i];
  450 +
  451 + // the send_message will free the msg,
  452 + // so set the msgs[i] to NULL.
  453 + msgs[i] = NULL;
  454 +
  455 + if ((ret = rtmp->send_message(msg)) != ERROR_SUCCESS) {
  456 + srs_error("send message to client failed. ret=%d", ret);
  457 + return ret;
  458 + }
  459 + }
  460 + }
  461 +
  462 + return ret;
  463 +}
  464 +
  465 +int SrsClient::fmle_publish(SrsSource* source)
  466 +{
  467 + int ret = ERROR_SUCCESS;
  468 +
  469 + if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {
  470 + srs_error("fmle check publish_refer failed. ret=%d", ret);
  471 + return ret;
  472 + }
  473 + srs_verbose("fmle check publish_refer success.");
  474 +
  475 + SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
  476 +
  477 + // notify the hls to prepare when publish start.
  478 + if ((ret = source->on_publish(req)) != ERROR_SUCCESS) {
  479 + srs_error("fmle hls on_publish failed. ret=%d", ret);
  480 + return ret;
  481 + }
  482 + srs_verbose("fmle hls on_publish success.");
  483 +
  484 + while (true) {
  485 + // switch to other st-threads.
  486 + st_usleep(0);
  487 +
  488 + SrsCommonMessage* msg = NULL;
  489 + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  490 + srs_error("fmle recv identify client message failed. ret=%d", ret);
  491 + return ret;
  492 + }
  493 +
  494 + SrsAutoFree(SrsCommonMessage, msg, false);
  495 +
  496 + pithy_print.set_age(msg->header.timestamp);
  497 +
  498 + // reportable
  499 + if (pithy_print.can_print()) {
  500 + srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  501 + pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  502 + }
  503 +
  504 + // process UnPublish event.
  505 + if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {
  506 + if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {
  507 + srs_error("fmle decode unpublish message failed. ret=%d", ret);
  508 + return ret;
  509 + }
  510 +
  511 + SrsPacket* pkt = msg->get_packet();
  512 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  513 + SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);
  514 + if ((ret = rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id)) != ERROR_SUCCESS) {
  515 + return ret;
  516 + }
  517 + return ERROR_CONTROL_REPUBLISH;
  518 + }
  519 +
  520 + srs_trace("fmle ignore AMF0/AMF3 command message.");
  521 + continue;
  522 + }
  523 +
  524 + // video, audio, data message
  525 + if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) {
  526 + srs_error("fmle process publish message failed. ret=%d", ret);
  527 + return ret;
  528 + }
  529 + }
  530 +
  531 + return ret;
  532 +}
  533 +
  534 +int SrsClient::flash_publish(SrsSource* source)
  535 +{
  536 + int ret = ERROR_SUCCESS;
  537 +
  538 + if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {
  539 + srs_error("flash check publish_refer failed. ret=%d", ret);
  540 + return ret;
  541 + }
  542 + srs_verbose("flash check publish_refer success.");
  543 +
  544 + SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
  545 +
  546 + // notify the hls to prepare when publish start.
  547 + if ((ret = source->on_publish(req)) != ERROR_SUCCESS) {
  548 + srs_error("flash hls on_publish failed. ret=%d", ret);
  549 + return ret;
  550 + }
  551 + srs_verbose("flash hls on_publish success.");
  552 +
  553 + while (true) {
  554 + // switch to other st-threads.
  555 + st_usleep(0);
  556 +
  557 + SrsCommonMessage* msg = NULL;
  558 + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  559 + if (!srs_is_client_gracefully_close(ret)) {
  560 + srs_error("flash recv identify client message failed. ret=%d", ret);
  561 + }
  562 + return ret;
  563 + }
  564 +
  565 + SrsAutoFree(SrsCommonMessage, msg, false);
  566 +
  567 + pithy_print.set_age(msg->header.timestamp);
  568 +
  569 + // reportable
  570 + if (pithy_print.can_print()) {
  571 + srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  572 + pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  573 + }
  574 +
  575 + // process UnPublish event.
  576 + if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {
  577 + if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {
  578 + srs_error("flash decode unpublish message failed. ret=%d", ret);
  579 + return ret;
  580 + }
  581 +
  582 + // flash unpublish.
  583 + // TODO: maybe need to support republish.
  584 + srs_trace("flash flash publish finished.");
  585 + return ERROR_CONTROL_REPUBLISH;
  586 + }
  587 +
  588 + // video, audio, data message
  589 + if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) {
  590 + srs_error("flash process publish message failed. ret=%d", ret);
  591 + return ret;
  592 + }
  593 + }
  594 +
  595 + return ret;
  596 +}
  597 +
  598 +int SrsClient::process_publish_message(SrsSource* source, SrsCommonMessage* msg)
  599 +{
  600 + int ret = ERROR_SUCCESS;
  601 +
  602 + // process audio packet
  603 + if (msg->header.is_audio()) {
  604 + if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) {
  605 + srs_error("source process audio message failed. ret=%d", ret);
  606 + return ret;
  607 + }
  608 + }
  609 + // process video packet
  610 + if (msg->header.is_video()) {
  611 + if ((ret = source->on_video(msg)) != ERROR_SUCCESS) {
  612 + srs_error("source process video message failed. ret=%d", ret);
  613 + return ret;
  614 + }
  615 + }
  616 +
  617 + // process onMetaData
  618 + if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
  619 + if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {
  620 + srs_error("decode onMetaData message failed. ret=%d", ret);
  621 + return ret;
  622 + }
  623 +
  624 + SrsPacket* pkt = msg->get_packet();
  625 + if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
  626 + SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
  627 + if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
  628 + srs_error("source process onMetaData message failed. ret=%d", ret);
  629 + return ret;
  630 + }
  631 + srs_trace("process onMetaData message success.");
  632 + return ret;
  633 + }
  634 +
  635 + srs_trace("ignore AMF0/AMF3 data message.");
  636 + return ret;
  637 + }
  638 +
  639 + return ret;
  640 +}
  641 +
  642 +int SrsClient::get_peer_ip()
  643 +{
  644 + int ret = ERROR_SUCCESS;
  645 +
  646 + int fd = st_netfd_fileno(stfd);
  647 +
  648 + // discovery client information
  649 + sockaddr_in addr;
  650 + socklen_t addrlen = sizeof(addr);
  651 + if (getpeername(fd, (sockaddr*)&addr, &addrlen) == -1) {
  652 + ret = ERROR_SOCKET_GET_PEER_NAME;
  653 + srs_error("discovery client information failed. ret=%d", ret);
  654 + return ret;
  655 + }
  656 + srs_verbose("get peer name success.");
  657 +
  658 + // ip v4 or v6
  659 + char buf[INET6_ADDRSTRLEN];
  660 + memset(buf, 0, sizeof(buf));
  661 +
  662 + if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) {
  663 + ret = ERROR_SOCKET_GET_PEER_IP;
  664 + srs_error("convert client information failed. ret=%d", ret);
  665 + return ret;
  666 + }
  667 + srs_verbose("get peer ip of client ip=%s, fd=%d", buf, fd);
  668 +
  669 + ip = new char[strlen(buf) + 1];
  670 + strcpy(ip, buf);
  671 +
  672 + srs_verbose("get peer ip success. ip=%s, fd=%d", ip, fd);
  673 +
  674 + return ret;
  675 +}
  676 +
  677 +int SrsClient::process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg)
  678 +{
  679 + int ret = ERROR_SUCCESS;
  680 +
  681 + if (!msg) {
  682 + srs_verbose("ignore all empty message.");
  683 + return ret;
  684 + }
  685 + SrsAutoFree(SrsCommonMessage, msg, false);
  686 +
  687 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  688 + srs_info("ignore all message except amf0/amf3 command.");
  689 + return ret;
  690 + }
  691 +
  692 + if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) {
  693 + srs_error("decode the amf0/amf3 command packet failed. ret=%d", ret);
  694 + return ret;
  695 + }
  696 + srs_info("decode the amf0/amf3 command packet success.");
  697 +
  698 + SrsCloseStreamPacket* close = dynamic_cast<SrsCloseStreamPacket*>(msg->get_packet());
  699 + if (close) {
  700 + ret = ERROR_CONTROL_RTMP_CLOSE;
  701 + srs_trace("system control message: rtmp close stream. ret=%d", ret);
  702 + return ret;
  703 + }
  704 +
  705 + SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(msg->get_packet());
  706 + if (!pause) {
  707 + srs_info("ignore all amf0/amf3 command except pause.");
  708 + return ret;
  709 + }
  710 +
  711 + if ((ret = rtmp->on_play_client_pause(res->stream_id, pause->is_pause)) != ERROR_SUCCESS) {
  712 + srs_error("rtmp process play client pause failed. ret=%d", ret);
  713 + return ret;
  714 + }
  715 +
  716 + if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) {
  717 + srs_error("consumer process play client pause failed. ret=%d", ret);
  718 + return ret;
  719 + }
  720 + srs_info("process pause success, is_pause=%d, time=%d.", pause->is_pause, pause->time_ms);
  721 +
  722 + return ret;
  723 +}
  724 +
  725 +int SrsClient::on_connect()
  726 +{
  727 + int ret = ERROR_SUCCESS;
  728 +
  729 +#ifdef SRS_HTTP_CALLBACK
  730 + // HTTP: on_connect
  731 + SrsConfDirective* on_connect = _srs_config->get_vhost_on_connect(req->vhost);
  732 + if (!on_connect) {
  733 + srs_info("ignore the empty http callback: on_connect");
  734 + return ret;
  735 + }
  736 +
  737 + for (int i = 0; i < (int)on_connect->args.size(); i++) {
  738 + std::string url = on_connect->args.at(i);
  739 + if ((ret = http_hooks->on_connect(url, connection_id, ip, req)) != ERROR_SUCCESS) {
  740 + srs_error("hook client on_connect failed. url=%s, ret=%d", url.c_str(), ret);
  741 + return ret;
  742 + }
  743 + }
  744 +#endif
  745 +
  746 + return ret;
  747 +}
  748 +
  749 +void SrsClient::on_close()
  750 +{
  751 +#ifdef SRS_HTTP_CALLBACK
  752 + // whatever the ret code, notify the api hooks.
  753 + // HTTP: on_close
  754 + SrsConfDirective* on_close = _srs_config->get_vhost_on_close(req->vhost);
  755 + if (!on_close) {
  756 + srs_info("ignore the empty http callback: on_close");
  757 + return;
  758 + }
  759 +
  760 + for (int i = 0; i < (int)on_close->args.size(); i++) {
  761 + std::string url = on_close->args.at(i);
  762 + http_hooks->on_close(url, connection_id, ip, req);
  763 + }
  764 +#endif
  765 +}
  766 +
  767 +int SrsClient::on_publish()
  768 +{
  769 + int ret = ERROR_SUCCESS;
  770 +
  771 +#ifdef SRS_HTTP_CALLBACK
  772 + // HTTP: on_publish
  773 + SrsConfDirective* on_publish = _srs_config->get_vhost_on_publish(req->vhost);
  774 + if (!on_publish) {
  775 + srs_info("ignore the empty http callback: on_publish");
  776 + return ret;
  777 + }
  778 +
  779 + for (int i = 0; i < (int)on_publish->args.size(); i++) {
  780 + std::string url = on_publish->args.at(i);
  781 + if ((ret = http_hooks->on_publish(url, connection_id, ip, req)) != ERROR_SUCCESS) {
  782 + srs_error("hook client on_publish failed. url=%s, ret=%d", url.c_str(), ret);
  783 + return ret;
  784 + }
  785 + }
  786 +#endif
  787 +
  788 + return ret;
  789 +}
  790 +
  791 +void SrsClient::on_unpublish()
  792 +{
  793 +#ifdef SRS_HTTP_CALLBACK
  794 + // whatever the ret code, notify the api hooks.
  795 + // HTTP: on_unpublish
  796 + SrsConfDirective* on_unpublish = _srs_config->get_vhost_on_unpublish(req->vhost);
  797 + if (!on_unpublish) {
  798 + srs_info("ignore the empty http callback: on_unpublish");
  799 + return;
  800 + }
  801 +
  802 + for (int i = 0; i < (int)on_unpublish->args.size(); i++) {
  803 + std::string url = on_unpublish->args.at(i);
  804 + http_hooks->on_unpublish(url, connection_id, ip, req);
  805 + }
  806 +#endif
  807 +}
  808 +
  809 +int SrsClient::on_play()
  810 +{
  811 + int ret = ERROR_SUCCESS;
  812 +
  813 +#ifdef SRS_HTTP_CALLBACK
  814 + // HTTP: on_play
  815 + SrsConfDirective* on_play = _srs_config->get_vhost_on_play(req->vhost);
  816 + if (!on_play) {
  817 + srs_info("ignore the empty http callback: on_play");
  818 + return ret;
  819 + }
  820 +
  821 + for (int i = 0; i < (int)on_play->args.size(); i++) {
  822 + std::string url = on_play->args.at(i);
  823 + if ((ret = http_hooks->on_play(url, connection_id, ip, req)) != ERROR_SUCCESS) {
  824 + srs_error("hook client on_play failed. url=%s, ret=%d", url.c_str(), ret);
  825 + return ret;
  826 + }
  827 + }
  828 +#endif
  829 +
  830 + return ret;
  831 +}
  832 +
  833 +void SrsClient::on_stop()
  834 +{
  835 +#ifdef SRS_HTTP_CALLBACK
  836 + // whatever the ret code, notify the api hooks.
  837 + // HTTP: on_stop
  838 + SrsConfDirective* on_stop = _srs_config->get_vhost_on_stop(req->vhost);
  839 + if (!on_stop) {
  840 + srs_info("ignore the empty http callback: on_stop");
  841 + return;
  842 + }
  843 +
  844 + for (int i = 0; i < (int)on_stop->args.size(); i++) {
  845 + std::string url = on_stop->args.at(i);
  846 + http_hooks->on_stop(url, connection_id, ip, req);
  847 + }
  848 +#endif
  849 +}