winlin

support http heartbeat, 0.9.107

@@ -42,13 +42,25 @@ max_connections 1000; @@ -42,13 +42,25 @@ max_connections 1000;
42 # default: on 42 # default: on
43 daemon on; 43 daemon on;
44 # heartbeat to api server 44 # heartbeat to api server
45 -# when startup, srs will heartbeat to this api.  
46 -# @remark: must be a restful http api url, where SRS will POST with following data:  
47 -# {  
48 -# "device_id": "my-srs-device",  
49 -# "ip": "192.168.1.100"  
50 -# }  
51 -heartbeat http://127.0.0.1:8085/api/v1/servers; 45 +heartbeat {
  46 + # whether heartbeat is enalbed.
  47 + # default: off
  48 + enabled off;
  49 + # the interval seconds for heartbeat,
  50 + # recommend 0.3,0.6,0.9,1.2,1.5,1.8,2.1,2.4,2.7,3,...,6,9,12,....
  51 + # default: 9.9
  52 + interval 9.3;
  53 + # when startup, srs will heartbeat to this api.
  54 + # @remark: must be a restful http api url, where SRS will POST with following data:
  55 + # {
  56 + # "device_id": "my-srs-device",
  57 + # "ip": "192.168.1.100"
  58 + # }
  59 + # default: http://127.0.0.1:8085/api/v1/servers
  60 + url http://127.0.0.1:8085/api/v1/servers;
  61 + # the id of devide.
  62 + device_id "my-srs-device";
  63 +}
52 64
53 ############################################################################################# 65 #############################################################################################
54 # HTTP sections 66 # HTTP sections
@@ -1422,17 +1422,6 @@ string SrsConfig::get_pid_file() @@ -1422,17 +1422,6 @@ string SrsConfig::get_pid_file()
1422 return conf->arg0(); 1422 return conf->arg0();
1423 } 1423 }
1424 1424
1425 -string SrsConfig::get_heartbeat_url()  
1426 -{  
1427 - SrsConfDirective* conf = root->get("heartbeat");  
1428 -  
1429 - if (!conf) {  
1430 - return "";  
1431 - }  
1432 -  
1433 - return conf->arg0();  
1434 -}  
1435 -  
1436 int SrsConfig::get_pithy_print_publish() 1425 int SrsConfig::get_pithy_print_publish()
1437 { 1426 {
1438 SrsConfDirective* pithy = root->get("pithy_print"); 1427 SrsConfDirective* pithy = root->get("pithy_print");
@@ -2787,6 +2776,74 @@ string SrsConfig::get_vhost_http_dir(string vhost) @@ -2787,6 +2776,74 @@ string SrsConfig::get_vhost_http_dir(string vhost)
2787 return conf->arg0(); 2776 return conf->arg0();
2788 } 2777 }
2789 2778
  2779 +SrsConfDirective* SrsConfig::get_heartbeart()
  2780 +{
  2781 + return root->get("heartbeat");
  2782 +}
  2783 +
  2784 +bool SrsConfig::get_heartbeat_enabled()
  2785 +{
  2786 + SrsConfDirective* conf = get_heartbeart();
  2787 +
  2788 + if (!conf) {
  2789 + return SRS_CONF_DEFAULT_HTTP_HEAETBEAT_ENABLED;
  2790 + }
  2791 +
  2792 + conf = conf->get("enabled");
  2793 + if (!conf || conf->arg0() != "on") {
  2794 + return SRS_CONF_DEFAULT_HTTP_HEAETBEAT_ENABLED;
  2795 + }
  2796 +
  2797 + return true;
  2798 +}
  2799 +
  2800 +int64_t SrsConfig::get_heartbeat_interval()
  2801 +{
  2802 + SrsConfDirective* conf = get_heartbeart();
  2803 +
  2804 + if (!conf) {
  2805 + return (int64_t)(SRS_CONF_DEFAULT_HTTP_HEAETBEAT_INTERVAL * 1000);
  2806 + }
  2807 + conf = conf->get("interval");
  2808 + if (!conf || conf->arg0().empty()) {
  2809 + return (int64_t)(SRS_CONF_DEFAULT_HTTP_HEAETBEAT_INTERVAL * 1000);
  2810 + }
  2811 +
  2812 + return (int64_t)(::atof(conf->arg0().c_str()) * 1000);
  2813 +}
  2814 +
  2815 +string SrsConfig::get_heartbeat_url()
  2816 +{
  2817 + SrsConfDirective* conf = get_heartbeart();
  2818 +
  2819 + if (!conf) {
  2820 + return SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL;
  2821 + }
  2822 +
  2823 + conf = conf->get("url");
  2824 + if (!conf || conf->arg0().empty()) {
  2825 + return SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL;
  2826 + }
  2827 +
  2828 + return conf->arg0();
  2829 +}
  2830 +
  2831 +string SrsConfig::get_heartbeat_device_id()
  2832 +{
  2833 + SrsConfDirective* conf = get_heartbeart();
  2834 +
  2835 + if (!conf) {
  2836 + return "";
  2837 + }
  2838 +
  2839 + conf = conf->get("device_id");
  2840 + if (!conf || conf->arg0().empty()) {
  2841 + return "";
  2842 + }
  2843 +
  2844 + return conf->arg0();
  2845 +}
  2846 +
2790 bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) 2847 bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
2791 { 2848 {
2792 // both NULL, equal. 2849 // both NULL, equal.
@@ -70,6 +70,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -70,6 +70,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
70 #define SRS_CONF_DEFAULT_HTTP_STREAM_PORT 8080 70 #define SRS_CONF_DEFAULT_HTTP_STREAM_PORT 8080
71 #define SRS_CONF_DEFAULT_HTTP_API_PORT 1985 71 #define SRS_CONF_DEFAULT_HTTP_API_PORT 1985
72 72
  73 +#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_ENABLED false
  74 +#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_INTERVAL 9.9
  75 +#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL "http://127.0.0.1:8085/api/v1/servers"
  76 +
73 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 10000 77 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 10000
74 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 10000 78 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 10000
75 #define SRS_STAGE_FORWARDER_INTERVAL_MS 10000 79 #define SRS_STAGE_FORWARDER_INTERVAL_MS 10000
@@ -173,7 +177,6 @@ public: @@ -173,7 +177,6 @@ public:
173 virtual int get_max_connections(); 177 virtual int get_max_connections();
174 virtual SrsConfDirective* get_listen(); 178 virtual SrsConfDirective* get_listen();
175 virtual std::string get_pid_file(); 179 virtual std::string get_pid_file();
176 - virtual std::string get_heartbeat_url();  
177 virtual int get_pithy_print_publish(); 180 virtual int get_pithy_print_publish();
178 virtual int get_pithy_print_forwarder(); 181 virtual int get_pithy_print_forwarder();
179 virtual int get_pithy_print_encoder(); 182 virtual int get_pithy_print_encoder();
@@ -286,6 +289,14 @@ public: @@ -286,6 +289,14 @@ public:
286 virtual bool get_vhost_http_enabled(std::string vhost); 289 virtual bool get_vhost_http_enabled(std::string vhost);
287 virtual std::string get_vhost_http_mount(std::string vhost); 290 virtual std::string get_vhost_http_mount(std::string vhost);
288 virtual std::string get_vhost_http_dir(std::string vhost); 291 virtual std::string get_vhost_http_dir(std::string vhost);
  292 +// http heartbeart section
  293 +private:
  294 + virtual SrsConfDirective* get_heartbeart();
  295 +public:
  296 + virtual bool get_heartbeat_enabled();
  297 + virtual int64_t get_heartbeat_interval();
  298 + virtual std::string get_heartbeat_url();
  299 + virtual std::string get_heartbeat_device_id();
289 }; 300 };
290 301
291 /** 302 /**
@@ -23,6 +23,68 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,6 +23,68 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_heartbeat.hpp> 24 #include <srs_app_heartbeat.hpp>
25 25
  26 +#ifdef SRS_AUTO_HTTP_PARSER
  27 +
  28 +#include <sstream>
  29 +using namespace std;
  30 +
26 #include <srs_kernel_error.hpp> 31 #include <srs_kernel_error.hpp>
27 #include <srs_kernel_log.hpp> 32 #include <srs_kernel_log.hpp>
  33 +#include <srs_app_config.hpp>
  34 +#include <srs_app_http_client.hpp>
  35 +#include <srs_app_json.hpp>
  36 +#include <srs_app_http.hpp>
  37 +#include <srs_app_utility.hpp>
  38 +
  39 +SrsHttpHeartbeat::SrsHttpHeartbeat()
  40 +{
  41 +}
  42 +
  43 +SrsHttpHeartbeat::~SrsHttpHeartbeat()
  44 +{
  45 +}
  46 +
  47 +void SrsHttpHeartbeat::heartbeat()
  48 +{
  49 + int ret = ERROR_SUCCESS;
  50 +
  51 + std::string url = _srs_config->get_heartbeat_url();
  52 +
  53 + SrsHttpUri uri;
  54 + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
  55 + srs_error("http uri parse hartbeart url failed. url=%s, ret=%d", url.c_str(), ret);
  56 + return;
  57 + }
  58 +
  59 + std::string ip = "";
  60 + std::string device_id = _srs_config->get_heartbeat_device_id();
  61 +
  62 + vector<string>& ips = srs_get_local_ipv4_ips();
  63 + if (!ips.empty()) {
  64 + ip = ips[0]; // TODO: FIXME: maybe need to config it.
  65 + }
  66 +
  67 + std::stringstream ss;
  68 + ss << JOBJECT_START
  69 + << JFIELD_STR("device_id", device_id) << JFIELD_CONT
  70 + << JFIELD_STR("ip", ip)
  71 + << JOBJECT_END;
  72 + std::string data = ss.str();
  73 + std::string res;
  74 +
  75 + SrsHttpClient http;
  76 + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) {
  77 + srs_error("http post hartbeart uri failed. "
  78 + "url=%s, request=%s, response=%s, ret=%d",
  79 + url.c_str(), data.c_str(), res.c_str(), ret);
  80 + return;
  81 + }
  82 +
  83 + srs_trace("http hook hartbeart success. "
  84 + "url=%s, request=%s, response=%s, ret=%d",
  85 + url.c_str(), data.c_str(), res.c_str(), ret);
  86 +
  87 + return;
  88 +}
28 89
  90 +#endif
@@ -29,4 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,4 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
  32 +#ifdef SRS_AUTO_HTTP_PARSER
  33 +
  34 +/**
  35 +* the http heartbeat to api-server to notice api
  36 +* that the information of SRS.
  37 +*/
  38 +class SrsHttpHeartbeat
  39 +{
  40 +public:
  41 + SrsHttpHeartbeat();
  42 + virtual ~SrsHttpHeartbeat();
  43 +public:
  44 + virtual void heartbeat();
  45 +public:
  46 + static void update_local_ipv4_ips();
  47 +};
  48 +
  49 +#endif
  50 +
32 #endif 51 #endif
@@ -23,3 +23,148 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,3 +23,148 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_http_client.hpp> 24 #include <srs_app_http_client.hpp>
25 25
  26 +#ifdef SRS_AUTO_HTTP_PARSER
  27 +
  28 +#include <arpa/inet.h>
  29 +
  30 +using namespace std;
  31 +
  32 +#include <srs_app_http.hpp>
  33 +#include <srs_kernel_error.hpp>
  34 +#include <srs_kernel_log.hpp>
  35 +#include <srs_app_socket.hpp>
  36 +
  37 +SrsHttpClient::SrsHttpClient()
  38 +{
  39 + connected = false;
  40 + stfd = NULL;
  41 + parser = NULL;
  42 +}
  43 +
  44 +SrsHttpClient::~SrsHttpClient()
  45 +{
  46 + disconnect();
  47 + srs_freep(parser);
  48 +}
  49 +
  50 +int SrsHttpClient::post(SrsHttpUri* uri, string req, string& res)
  51 +{
  52 + res = "";
  53 +
  54 + int ret = ERROR_SUCCESS;
  55 +
  56 + if (!parser) {
  57 + parser = new SrsHttpParser();
  58 +
  59 + if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) {
  60 + srs_error("initialize parser failed. ret=%d", ret);
  61 + return ret;
  62 + }
  63 + }
  64 +
  65 + if ((ret = connect(uri)) != ERROR_SUCCESS) {
  66 + srs_error("http connect server failed. ret=%d", ret);
  67 + return ret;
  68 + }
  69 +
  70 + // send POST request to uri
  71 + // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
  72 + std::stringstream ss;
  73 + ss << "POST " << uri->get_path() << " "
  74 + << "HTTP/1.1" << __CRLF
  75 + << "Host: " << uri->get_host() << __CRLF
  76 + << "Connection: Keep-Alive" << __CRLF
  77 + << "Content-Length: " << std::dec << req.length() << __CRLF
  78 + << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __CRLF
  79 + << "Content-Type: text/html" << __CRLF
  80 + << __CRLF
  81 + << req;
  82 +
  83 + SrsSocket skt(stfd);
  84 +
  85 + std::string data = ss.str();
  86 + if ((ret = skt.write(data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
  87 + // disconnect when error.
  88 + disconnect();
  89 +
  90 + srs_error("write http post failed. ret=%d", ret);
  91 + return ret;
  92 + }
  93 +
  94 + SrsHttpMessage* msg = NULL;
  95 + if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) {
  96 + srs_error("parse http post response failed. ret=%d", ret);
  97 + return ret;
  98 + }
  99 +
  100 + srs_assert(msg);
  101 + srs_assert(msg->is_complete());
  102 +
  103 + // get response body.
  104 + if (msg->body_size() > 0) {
  105 + res = msg->body();
  106 + }
  107 + srs_info("parse http post response success.");
  108 +
  109 + return ret;
  110 +}
  111 +
  112 +void SrsHttpClient::disconnect()
  113 +{
  114 + connected = false;
  115 +
  116 + srs_close_stfd(stfd);
  117 +}
  118 +
  119 +int SrsHttpClient::connect(SrsHttpUri* uri)
  120 +{
  121 + int ret = ERROR_SUCCESS;
  122 +
  123 + if (connected) {
  124 + return ret;
  125 + }
  126 +
  127 + disconnect();
  128 +
  129 + std::string ip = srs_dns_resolve(uri->get_host());
  130 + if (ip.empty()) {
  131 + ret = ERROR_SYSTEM_IP_INVALID;
  132 + srs_error("dns resolve server error, ip empty. ret=%d", ret);
  133 + return ret;
  134 + }
  135 +
  136 + int sock = socket(AF_INET, SOCK_STREAM, 0);
  137 + if(sock == -1){
  138 + ret = ERROR_SOCKET_CREATE;
  139 + srs_error("create socket error. ret=%d", ret);
  140 + return ret;
  141 + }
  142 +
  143 + stfd = st_netfd_open_socket(sock);
  144 + if(stfd == NULL){
  145 + ret = ERROR_ST_OPEN_SOCKET;
  146 + srs_error("st_netfd_open_socket failed. ret=%d", ret);
  147 + return ret;
  148 + }
  149 +
  150 + sockaddr_in addr;
  151 + addr.sin_family = AF_INET;
  152 + addr.sin_port = htons(uri->get_port());
  153 + addr.sin_addr.s_addr = inet_addr(ip.c_str());
  154 +
  155 + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
  156 + ret = ERROR_ST_CONNECT;
  157 + srs_error("connect to server error. "
  158 + "ip=%s, port=%d, ret=%d", ip.c_str(), uri->get_port(), ret);
  159 + return ret;
  160 + }
  161 + srs_info("connect to server success. "
  162 + "http url=%s, server=%s, ip=%s, port=%d",
  163 + uri->get_url(), uri->get_host(), ip.c_str(), uri->get_port());
  164 +
  165 + connected = true;
  166 +
  167 + return ret;
  168 +}
  169 +
  170 +#endif
@@ -29,4 +29,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,4 +29,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
  32 +#ifdef SRS_AUTO_HTTP_PARSER
  33 +
  34 +#include <srs_app_st.hpp>
  35 +
  36 +class SrsHttpUri;
  37 +class SrsHttpParser;
  38 +
  39 +/**
  40 +* http client to GET/POST/PUT/DELETE uri
  41 +*/
  42 +class SrsHttpClient
  43 +{
  44 +private:
  45 + bool connected;
  46 + st_netfd_t stfd;
  47 + SrsHttpParser* parser;
  48 +public:
  49 + SrsHttpClient();
  50 + virtual ~SrsHttpClient();
  51 +public:
  52 + /**
  53 + * to post data to the uri.
  54 + * @param req the data post to uri.
  55 + * @param res the response data from server.
  56 + */
  57 + virtual int post(SrsHttpUri* uri, std::string req, std::string& res);
  58 +private:
  59 + virtual void disconnect();
  60 + virtual int connect(SrsHttpUri* uri);
  61 +};
  62 +
  63 +#endif
  64 +
32 #endif 65 #endif
@@ -28,8 +28,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,8 +28,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include <sstream> 28 #include <sstream>
29 using namespace std; 29 using namespace std;
30 30
31 -#include <arpa/inet.h>  
32 -  
33 #include <srs_kernel_error.hpp> 31 #include <srs_kernel_error.hpp>
34 #include <srs_protocol_rtmp.hpp> 32 #include <srs_protocol_rtmp.hpp>
35 #include <srs_kernel_log.hpp> 33 #include <srs_kernel_log.hpp>
@@ -38,145 +36,13 @@ using namespace std; @@ -38,145 +36,13 @@ using namespace std;
38 #include <srs_app_json.hpp> 36 #include <srs_app_json.hpp>
39 #include <srs_app_dvr.hpp> 37 #include <srs_app_dvr.hpp>
40 #include <srs_app_config.hpp> 38 #include <srs_app_config.hpp>
  39 +#include <srs_app_http_client.hpp>
41 40
42 #define SRS_HTTP_RESPONSE_OK "0" 41 #define SRS_HTTP_RESPONSE_OK "0"
43 42
44 #define SRS_HTTP_HEADER_BUFFER 1024 43 #define SRS_HTTP_HEADER_BUFFER 1024
45 #define SRS_HTTP_BODY_BUFFER 32 * 1024 44 #define SRS_HTTP_BODY_BUFFER 32 * 1024
46 45
47 -SrsHttpClient::SrsHttpClient()  
48 -{  
49 - connected = false;  
50 - stfd = NULL;  
51 - parser = NULL;  
52 -}  
53 -  
54 -SrsHttpClient::~SrsHttpClient()  
55 -{  
56 - disconnect();  
57 - srs_freep(parser);  
58 -}  
59 -  
60 -int SrsHttpClient::post(SrsHttpUri* uri, string req, string& res)  
61 -{  
62 - res = "";  
63 -  
64 - int ret = ERROR_SUCCESS;  
65 -  
66 - if (!parser) {  
67 - parser = new SrsHttpParser();  
68 -  
69 - if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) {  
70 - srs_error("initialize parser failed. ret=%d", ret);  
71 - return ret;  
72 - }  
73 - }  
74 -  
75 - if ((ret = connect(uri)) != ERROR_SUCCESS) {  
76 - srs_error("http connect server failed. ret=%d", ret);  
77 - return ret;  
78 - }  
79 -  
80 - // send POST request to uri  
81 - // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s  
82 - std::stringstream ss;  
83 - ss << "POST " << uri->get_path() << " "  
84 - << "HTTP/1.1" << __CRLF  
85 - << "Host: " << uri->get_host() << __CRLF  
86 - << "Connection: Keep-Alive" << __CRLF  
87 - << "Content-Length: " << std::dec << req.length() << __CRLF  
88 - << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __CRLF  
89 - << "Content-Type: text/html" << __CRLF  
90 - << __CRLF  
91 - << req;  
92 -  
93 - SrsSocket skt(stfd);  
94 -  
95 - std::string data = ss.str();  
96 - if ((ret = skt.write(data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {  
97 - // disconnect when error.  
98 - disconnect();  
99 -  
100 - srs_error("write http post failed. ret=%d", ret);  
101 - return ret;  
102 - }  
103 -  
104 - SrsHttpMessage* msg = NULL;  
105 - if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) {  
106 - srs_error("parse http post response failed. ret=%d", ret);  
107 - return ret;  
108 - }  
109 -  
110 - srs_assert(msg);  
111 - srs_assert(msg->is_complete());  
112 -  
113 - // get response body.  
114 - if (msg->body_size() > 0) {  
115 - res = msg->body();  
116 - }  
117 - srs_info("parse http post response success.");  
118 -  
119 - return ret;  
120 -}  
121 -  
122 -void SrsHttpClient::disconnect()  
123 -{  
124 - connected = false;  
125 -  
126 - srs_close_stfd(stfd);  
127 -}  
128 -  
129 -int SrsHttpClient::connect(SrsHttpUri* uri)  
130 -{  
131 - int ret = ERROR_SUCCESS;  
132 -  
133 - if (connected) {  
134 - return ret;  
135 - }  
136 -  
137 - disconnect();  
138 -  
139 - std::string ip = srs_dns_resolve(uri->get_host());  
140 - if (ip.empty()) {  
141 - ret = ERROR_SYSTEM_IP_INVALID;  
142 - srs_error("dns resolve server error, ip empty. ret=%d", ret);  
143 - return ret;  
144 - }  
145 -  
146 - int sock = socket(AF_INET, SOCK_STREAM, 0);  
147 - if(sock == -1){  
148 - ret = ERROR_SOCKET_CREATE;  
149 - srs_error("create socket error. ret=%d", ret);  
150 - return ret;  
151 - }  
152 -  
153 - stfd = st_netfd_open_socket(sock);  
154 - if(stfd == NULL){  
155 - ret = ERROR_ST_OPEN_SOCKET;  
156 - srs_error("st_netfd_open_socket failed. ret=%d", ret);  
157 - return ret;  
158 - }  
159 -  
160 - sockaddr_in addr;  
161 - addr.sin_family = AF_INET;  
162 - addr.sin_port = htons(uri->get_port());  
163 - addr.sin_addr.s_addr = inet_addr(ip.c_str());  
164 -  
165 - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){  
166 - ret = ERROR_ST_CONNECT;  
167 - srs_error("connect to server error. "  
168 - "ip=%s, port=%d, ret=%d", ip.c_str(), uri->get_port(), ret);  
169 - return ret;  
170 - }  
171 - srs_info("connect to server success. "  
172 - "http url=%s, server=%s, ip=%s, port=%d",  
173 - uri->get_url(), uri->get_host(), ip.c_str(), uri->get_port());  
174 -  
175 - connected = true;  
176 -  
177 - return ret;  
178 -}  
179 -  
180 SrsHttpHooks::SrsHttpHooks() 46 SrsHttpHooks::SrsHttpHooks()
181 { 47 {
182 } 48 }
@@ -39,32 +39,6 @@ class SrsRequest; @@ -39,32 +39,6 @@ class SrsRequest;
39 class SrsHttpParser; 39 class SrsHttpParser;
40 class SrsFlvSegment; 40 class SrsFlvSegment;
41 41
42 -#include <srs_app_st.hpp>  
43 -  
44 -/**  
45 -* http client to GET/POST/PUT/DELETE uri  
46 -*/  
47 -class SrsHttpClient  
48 -{  
49 -private:  
50 - bool connected;  
51 - st_netfd_t stfd;  
52 - SrsHttpParser* parser;  
53 -public:  
54 - SrsHttpClient();  
55 - virtual ~SrsHttpClient();  
56 -public:  
57 - /**  
58 - * to post data to the uri.  
59 - * @param req the data post to uri.  
60 - * @param res the response data from server.  
61 - */  
62 - virtual int post(SrsHttpUri* uri, std::string req, std::string& res);  
63 -private:  
64 - virtual void disconnect();  
65 - virtual int connect(SrsHttpUri* uri);  
66 -};  
67 -  
68 /** 42 /**
69 * the http hooks, http callback api, 43 * the http hooks, http callback api,
70 * for some event, such as on_connect, call 44 * for some event, such as on_connect, call
@@ -41,11 +41,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -41,11 +41,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 #include <srs_app_http_api.hpp> 41 #include <srs_app_http_api.hpp>
42 #include <srs_app_http_conn.hpp> 42 #include <srs_app_http_conn.hpp>
43 #include <srs_app_http.hpp> 43 #include <srs_app_http.hpp>
44 -#ifdef SRS_AUTO_INGEST  
45 #include <srs_app_ingest.hpp> 44 #include <srs_app_ingest.hpp>
46 -#endif  
47 #include <srs_app_source.hpp> 45 #include <srs_app_source.hpp>
48 #include <srs_app_utility.hpp> 46 #include <srs_app_utility.hpp>
  47 +#include <srs_app_heartbeat.hpp>
49 48
50 #define SERVER_LISTEN_BACKLOG 512 49 #define SERVER_LISTEN_BACKLOG 512
51 50
@@ -74,7 +73,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -74,7 +73,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
74 73
75 // update platform info interval: 74 // update platform info interval:
76 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES 75 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES
77 -#define SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES 80 76 +#define SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES 90
78 77
79 SrsListener::SrsListener(SrsServer* server, SrsListenerType type) 78 SrsListener::SrsListener(SrsServer* server, SrsListenerType type)
80 { 79 {
@@ -317,6 +316,9 @@ SrsServer::SrsServer() @@ -317,6 +316,9 @@ SrsServer::SrsServer()
317 #ifdef SRS_AUTO_HTTP_SERVER 316 #ifdef SRS_AUTO_HTTP_SERVER
318 http_stream_handler = NULL; 317 http_stream_handler = NULL;
319 #endif 318 #endif
  319 +#ifdef SRS_AUTO_HTTP_PARSER
  320 + http_heartbeat = NULL;
  321 +#endif
320 #ifdef SRS_AUTO_INGEST 322 #ifdef SRS_AUTO_INGEST
321 ingester = NULL; 323 ingester = NULL;
322 #endif 324 #endif
@@ -348,6 +350,11 @@ void SrsServer::destroy() @@ -348,6 +350,11 @@ void SrsServer::destroy()
348 #ifdef SRS_AUTO_HTTP_SERVER 350 #ifdef SRS_AUTO_HTTP_SERVER
349 srs_freep(http_stream_handler); 351 srs_freep(http_stream_handler);
350 #endif 352 #endif
  353 +
  354 +#ifdef SRS_AUTO_HTTP_PARSER
  355 + srs_freep(http_heartbeat);
  356 +#endif
  357 +
351 #ifdef SRS_AUTO_INGEST 358 #ifdef SRS_AUTO_INGEST
352 srs_freep(ingester); 359 srs_freep(ingester);
353 #endif 360 #endif
@@ -392,6 +399,10 @@ int SrsServer::initialize() @@ -392,6 +399,10 @@ int SrsServer::initialize()
392 srs_assert(!http_stream_handler); 399 srs_assert(!http_stream_handler);
393 http_stream_handler = SrsHttpHandler::create_http_stream(); 400 http_stream_handler = SrsHttpHandler::create_http_stream();
394 #endif 401 #endif
  402 +#ifdef SRS_AUTO_HTTP_PARSER
  403 + srs_assert(!http_heartbeat);
  404 + http_heartbeat = new SrsHttpHeartbeat();
  405 +#endif
395 #ifdef SRS_AUTO_INGEST 406 #ifdef SRS_AUTO_INGEST
396 srs_assert(!ingester); 407 srs_assert(!ingester);
397 ingester = new SrsIngester(); 408 ingester = new SrsIngester();
@@ -635,7 +646,14 @@ int SrsServer::do_cycle() @@ -635,7 +646,14 @@ int SrsServer::do_cycle()
635 646
636 // the deamon thread, update the time cache 647 // the deamon thread, update the time cache
637 while (true) { 648 while (true) {
638 - for (int i = 1; i < max + 1; i++) { 649 + // the interval in config.
  650 + int64_t heartbeat_max_resolution = _srs_config->get_heartbeat_interval() / 100;
  651 +
  652 + // dynamic fetch the max.
  653 + int __max = max;
  654 + __max = srs_max(__max, heartbeat_max_resolution);
  655 +
  656 + for (int i = 1; i < __max + 1; i++) {
639 st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); 657 st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
640 658
641 // for gperf heap checker, 659 // for gperf heap checker,
@@ -677,6 +695,13 @@ int SrsServer::do_cycle() @@ -677,6 +695,13 @@ int SrsServer::do_cycle()
677 if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) { 695 if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
678 srs_update_platform_info(); 696 srs_update_platform_info();
679 } 697 }
  698 +#ifdef SRS_AUTO_HTTP_PARSER
  699 + if (_srs_config->get_heartbeat_enabled()) {
  700 + if ((i % heartbeat_max_resolution) == 0) {
  701 + http_heartbeat->heartbeat();
  702 + }
  703 + }
  704 +#endif
680 } 705 }
681 } 706 }
682 707
@@ -40,6 +40,7 @@ class SrsServer; @@ -40,6 +40,7 @@ class SrsServer;
40 class SrsConnection; 40 class SrsConnection;
41 class SrsHttpHandler; 41 class SrsHttpHandler;
42 class SrsIngester; 42 class SrsIngester;
  43 +class SrsHttpHeartbeat;
43 44
44 // listener type for server to identify the connection, 45 // listener type for server to identify the connection,
45 // that is, use different type to process the connection. 46 // that is, use different type to process the connection.
@@ -115,6 +116,9 @@ private: @@ -115,6 +116,9 @@ private:
115 #ifdef SRS_AUTO_HTTP_SERVER 116 #ifdef SRS_AUTO_HTTP_SERVER
116 SrsHttpHandler* http_stream_handler; 117 SrsHttpHandler* http_stream_handler;
117 #endif 118 #endif
  119 +#ifdef SRS_AUTO_HTTP_PARSER
  120 + SrsHttpHeartbeat* http_heartbeat;
  121 +#endif
118 #ifdef SRS_AUTO_INGEST 122 #ifdef SRS_AUTO_INGEST
119 SrsIngester* ingester; 123 SrsIngester* ingester;
120 #endif 124 #endif
@@ -23,12 +23,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,12 +23,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_utility.hpp> 24 #include <srs_app_utility.hpp>
25 25
  26 +#include <sys/types.h>
26 #include <unistd.h> 27 #include <unistd.h>
  28 +#include <ifaddrs.h>
  29 +#include <arpa/inet.h>
  30 +
  31 +using namespace std;
27 32
28 #include <srs_kernel_log.hpp> 33 #include <srs_kernel_log.hpp>
29 #include <srs_app_config.hpp> 34 #include <srs_app_config.hpp>
30 #include <srs_kernel_utility.hpp> 35 #include <srs_kernel_utility.hpp>
31 36
  37 +#define SRS_LOCAL_LOOP_IP "127.0.0.1"
  38 +
32 int srs_get_log_level(std::string level) 39 int srs_get_log_level(std::string level)
33 { 40 {
34 if ("verbose" == _srs_config->get_log_level()) { 41 if ("verbose" == _srs_config->get_log_level()) {
@@ -435,3 +442,55 @@ void srs_update_platform_info() @@ -435,3 +442,55 @@ void srs_update_platform_info()
435 } 442 }
436 } 443 }
437 } 444 }
  445 +
  446 +vector<string> _srs_system_ipv4_ips;
  447 +
  448 +void retrieve_local_ipv4_ips()
  449 +{
  450 + vector<string>& ips = _srs_system_ipv4_ips;
  451 +
  452 + ips.clear();
  453 +
  454 + ifaddrs* ifap;
  455 + if (getifaddrs(&ifap) == -1) {
  456 + srs_warn("retrieve local ips, ini ifaddrs failed.");
  457 + return;
  458 + }
  459 +
  460 + ifaddrs* p = ifap;
  461 + while (p != NULL) {
  462 + sockaddr* addr = p->ifa_addr;
  463 +
  464 + // retrieve ipv4 addr
  465 + if (addr->sa_family == AF_INET) {
  466 + in_addr* inaddr = &((sockaddr_in*)addr)->sin_addr;
  467 +
  468 + char buf[16];
  469 + memset(buf, 0, sizeof(buf));
  470 +
  471 + if ((inet_ntop(addr->sa_family, inaddr, buf, sizeof(buf))) == NULL) {
  472 + srs_warn("convert local ip failed");
  473 + break;
  474 + }
  475 +
  476 + std::string ip = buf;
  477 + if (ip != SRS_LOCAL_LOOP_IP) {
  478 + srs_trace("retrieve local ipv4 addresses: %s", ip.c_str());
  479 + ips.push_back(ip);
  480 + }
  481 + }
  482 +
  483 + p = p->ifa_next;
  484 + }
  485 +
  486 + freeifaddrs(ifap);
  487 +}
  488 +
  489 +vector<string>& srs_get_local_ipv4_ips()
  490 +{
  491 + if (_srs_system_ipv4_ips.empty()) {
  492 + retrieve_local_ipv4_ips();
  493 + }
  494 +
  495 + return _srs_system_ipv4_ips;
  496 +}
@@ -30,6 +30,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,6 +30,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +#include <vector>
  34 +#include <string>
  35 +
33 #include <sys/resource.h> 36 #include <sys/resource.h>
34 37
35 /** 38 /**
@@ -346,4 +349,8 @@ extern SrsPlatformInfo* srs_get_platform_info(); @@ -346,4 +349,8 @@ extern SrsPlatformInfo* srs_get_platform_info();
346 // the deamon st-thread will update it. 349 // the deamon st-thread will update it.
347 extern void srs_update_platform_info(); 350 extern void srs_update_platform_info();
348 351
  352 +// get local ip, fill to @param ips
  353 +extern void srs_retrieve_local_ipv4_ips();
  354 +extern std::vector<std::string>& srs_get_local_ipv4_ips();
  355 +
349 #endif 356 #endif
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "106" 34 +#define VERSION_REVISION "107"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"