正在显示
8 个修改的文件
包含
113 行增加
和
2 行删除
| 1 | Simple-RTMP-Server | 1 | Simple-RTMP-Server |
| 2 | ================== | 2 | ================== |
| 3 | 3 | ||
| 4 | -SRS(SIMPLE RTMP Server) over state-threads created in 2013. | 4 | +SRS(SIMPLE RTMP Server) over state-threads created in 2013.10. |
| 5 | 5 | ||
| 6 | SRS is a simple, [RTMP](https://github.com/winlinvip/simple-rtmp-server/wiki/DeliveryRTMP)/[HLS](https://github.com/winlinvip/simple-rtmp-server/wiki/DeliveryHLS), | 6 | SRS is a simple, [RTMP](https://github.com/winlinvip/simple-rtmp-server/wiki/DeliveryRTMP)/[HLS](https://github.com/winlinvip/simple-rtmp-server/wiki/DeliveryHLS), |
| 7 | [high-performance](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance), single/multiple(plan) processes, edge(plan)/origin live server, | 7 | [high-performance](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance), single/multiple(plan) processes, edge(plan)/origin live server, |
| @@ -169,6 +169,7 @@ See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-serv | @@ -169,6 +169,7 @@ See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-serv | ||
| 169 | * nginx v1.5.0: 139524 lines <br/> | 169 | * nginx v1.5.0: 139524 lines <br/> |
| 170 | 170 | ||
| 171 | ### History | 171 | ### History |
| 172 | +* v1.0, 2014-03-21, write pid to ./objs/srs.pid. | ||
| 172 | * v1.0, 2014-03-20, refine hls code, support pure audio HLS. | 173 | * v1.0, 2014-03-20, refine hls code, support pure audio HLS. |
| 173 | * v1.0, 2014-03-19, add vn/an for FFMPEG to drop video/audio for radio stream. | 174 | * v1.0, 2014-03-19, add vn/an for FFMPEG to drop video/audio for radio stream. |
| 174 | * v1.0, 2014-03-19, refine handshake, client support coplex handshake, add utest. | 175 | * v1.0, 2014-03-19, refine handshake, client support coplex handshake, add utest. |
| @@ -429,7 +430,7 @@ Bandwidth Test Workflow: | @@ -429,7 +430,7 @@ Bandwidth Test Workflow: | ||
| 429 | @See: class SrsBandwidth comments. | 430 | @See: class SrsBandwidth comments. |
| 430 | </pre> | 431 | </pre> |
| 431 | 432 | ||
| 432 | -Beijing, 2013<br/> | 433 | +Beijing, 2013.10<br/> |
| 433 | Winlin | 434 | Winlin |
| 434 | 435 | ||
| 435 | 436 |
| @@ -2,6 +2,12 @@ | @@ -2,6 +2,12 @@ | ||
| 2 | 2 | ||
| 3 | # the listen ports, split by space. | 3 | # the listen ports, split by space. |
| 4 | listen 1935; | 4 | listen 1935; |
| 5 | +# the pid file | ||
| 6 | +# to ensure only one process can use a pid file | ||
| 7 | +# and provides the current running process id, for script, | ||
| 8 | +# for example, init.d script to manage the server. | ||
| 9 | +# default: ./objs/srs.pid | ||
| 10 | +pid ./objs/srs.pid; | ||
| 5 | # the default chunk size is 128, max is 65536, | 11 | # the default chunk size is 128, max is 65536, |
| 6 | # some client does not support chunk size change, | 12 | # some client does not support chunk size change, |
| 7 | # however, most clients supports it and it can improve | 13 | # however, most clients supports it and it can improve |
| @@ -682,6 +682,7 @@ int SrsConfig::parse_file(const char* filename) | @@ -682,6 +682,7 @@ int SrsConfig::parse_file(const char* filename) | ||
| 682 | // TODO: check forward. | 682 | // TODO: check forward. |
| 683 | // TODO: check ffmpeg. | 683 | // TODO: check ffmpeg. |
| 684 | // TODO: check http. | 684 | // TODO: check http. |
| 685 | + // TODO: check pid. | ||
| 685 | 686 | ||
| 686 | return ret; | 687 | return ret; |
| 687 | } | 688 | } |
| @@ -1440,6 +1441,17 @@ SrsConfDirective* SrsConfig::get_listen() | @@ -1440,6 +1441,17 @@ SrsConfDirective* SrsConfig::get_listen() | ||
| 1440 | return root->get("listen"); | 1441 | return root->get("listen"); |
| 1441 | } | 1442 | } |
| 1442 | 1443 | ||
| 1444 | +string SrsConfig::get_pid_file() | ||
| 1445 | +{ | ||
| 1446 | + SrsConfDirective* conf = root->get("pid"); | ||
| 1447 | + | ||
| 1448 | + if (!conf) { | ||
| 1449 | + return SRS_CONF_DEFAULT_PID_FILE; | ||
| 1450 | + } | ||
| 1451 | + | ||
| 1452 | + return conf->arg0(); | ||
| 1453 | +} | ||
| 1454 | + | ||
| 1443 | int SrsConfig::get_chunk_size(const std::string &vhost) | 1455 | int SrsConfig::get_chunk_size(const std::string &vhost) |
| 1444 | { | 1456 | { |
| 1445 | SrsConfDirective* conf = get_vhost(vhost); | 1457 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 38 | #define RTMP_VHOST_DEFAULT "__defaultVhost__" | 38 | #define RTMP_VHOST_DEFAULT "__defaultVhost__" |
| 39 | 39 | ||
| 40 | #define SRS_LOCALHOST "127.0.0.1" | 40 | #define SRS_LOCALHOST "127.0.0.1" |
| 41 | +#define SRS_CONF_DEFAULT_PID_FILE "./objs/srs.pid" | ||
| 41 | 42 | ||
| 42 | #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" | 43 | #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" |
| 43 | #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10 | 44 | #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10 |
| @@ -162,6 +163,7 @@ public: | @@ -162,6 +163,7 @@ public: | ||
| 162 | virtual SrsConfDirective* get_refer_play(std::string vhost); | 163 | virtual SrsConfDirective* get_refer_play(std::string vhost); |
| 163 | virtual SrsConfDirective* get_refer_publish(std::string vhost); | 164 | virtual SrsConfDirective* get_refer_publish(std::string vhost); |
| 164 | virtual SrsConfDirective* get_listen(); | 165 | virtual SrsConfDirective* get_listen(); |
| 166 | + virtual std::string get_pid_file(); | ||
| 165 | virtual int get_chunk_size(const std::string& vhost); | 167 | virtual int get_chunk_size(const std::string& vhost); |
| 166 | virtual int get_pithy_print_publish(); | 168 | virtual int get_pithy_print_publish(); |
| 167 | virtual int get_pithy_print_forwarder(); | 169 | virtual int get_pithy_print_forwarder(); |
| @@ -27,6 +27,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -27,6 +27,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 27 | #include <sys/socket.h> | 27 | #include <sys/socket.h> |
| 28 | #include <arpa/inet.h> | 28 | #include <arpa/inet.h> |
| 29 | #include <signal.h> | 29 | #include <signal.h> |
| 30 | +#include <sys/types.h> | ||
| 31 | +#include <sys/stat.h> | ||
| 32 | +#include <fcntl.h> | ||
| 30 | 33 | ||
| 31 | #include <algorithm> | 34 | #include <algorithm> |
| 32 | 35 | ||
| @@ -198,6 +201,81 @@ int SrsServer::initialize() | @@ -198,6 +201,81 @@ int SrsServer::initialize() | ||
| 198 | return ret; | 201 | return ret; |
| 199 | } | 202 | } |
| 200 | 203 | ||
| 204 | +int SrsServer::acquire_pid_file() | ||
| 205 | +{ | ||
| 206 | + int ret = ERROR_SUCCESS; | ||
| 207 | + | ||
| 208 | + std::string pid_file = _srs_config->get_pid_file(); | ||
| 209 | + | ||
| 210 | + // -rw-r--r-- | ||
| 211 | + // 644 | ||
| 212 | + int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; | ||
| 213 | + | ||
| 214 | + int fd; | ||
| 215 | + // open pid file | ||
| 216 | + if ((fd = ::open(pid_file.c_str(), O_WRONLY | O_CREAT, mode)) < 0) { | ||
| 217 | + ret = ERROR_SYSTEM_PID_ACQUIRE; | ||
| 218 | + srs_error("open pid file %s error, ret=%#x", pid_file.c_str(), ret); | ||
| 219 | + return ret; | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + // require write lock | ||
| 223 | + flock lock; | ||
| 224 | + | ||
| 225 | + lock.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, F_UNLCK | ||
| 226 | + lock.l_start = 0; // type offset, relative to l_whence | ||
| 227 | + lock.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END | ||
| 228 | + lock.l_len = 0; | ||
| 229 | + | ||
| 230 | + if (fcntl(fd, F_SETLK, &lock) < 0) { | ||
| 231 | + if(errno == EACCES || errno == EAGAIN) { | ||
| 232 | + ret = ERROR_SYSTEM_PID_ALREADY_RUNNING; | ||
| 233 | + srs_error("srs is already running! ret=%#x", ret); | ||
| 234 | + return ret; | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + ret = ERROR_SYSTEM_PID_LOCK; | ||
| 238 | + srs_error("require lock for file %s error! ret=%#x", pid_file.c_str(), ret); | ||
| 239 | + return ret; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + // truncate file | ||
| 243 | + if (ftruncate(fd, 0) < 0) { | ||
| 244 | + ret = ERROR_SYSTEM_PID_TRUNCATE_FILE; | ||
| 245 | + srs_error("truncate pid file %s error! ret=%#x", pid_file.c_str(), ret); | ||
| 246 | + return ret; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + int pid = (int)getpid(); | ||
| 250 | + | ||
| 251 | + // write the pid | ||
| 252 | + char buf[512]; | ||
| 253 | + snprintf(buf, sizeof(buf), "%d", pid); | ||
| 254 | + if (write(fd, buf, strlen(buf)) != (int)strlen(buf)) { | ||
| 255 | + ret = ERROR_SYSTEM_PID_WRITE_FILE; | ||
| 256 | + srs_error("write our pid error! pid=%d file=%s ret=%#x", pid, pid_file.c_str(), ret); | ||
| 257 | + return ret; | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + // auto close when fork child process. | ||
| 261 | + int val; | ||
| 262 | + if ((val = fcntl(fd, F_GETFD, 0)) < 0) { | ||
| 263 | + ret = ERROR_SYSTEM_PID_GET_FILE_INFO; | ||
| 264 | + srs_error("fnctl F_GETFD error! file=%s ret=%#x", pid_file.c_str(), ret); | ||
| 265 | + return ret; | ||
| 266 | + } | ||
| 267 | + val |= FD_CLOEXEC; | ||
| 268 | + if (fcntl(fd, F_SETFD, val) < 0) { | ||
| 269 | + ret = ERROR_SYSTEM_PID_SET_FILE_INFO; | ||
| 270 | + srs_error("fcntl F_SETFD error! file=%s ret=%#x", pid_file.c_str(), ret); | ||
| 271 | + return ret; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + srs_trace("write pid=%d to %s success!", pid, pid_file.c_str()); | ||
| 275 | + | ||
| 276 | + return ret; | ||
| 277 | +} | ||
| 278 | + | ||
| 201 | int SrsServer::listen() | 279 | int SrsServer::listen() |
| 202 | { | 280 | { |
| 203 | int ret = ERROR_SUCCESS; | 281 | int ret = ERROR_SUCCESS; |
| @@ -79,6 +79,7 @@ public: | @@ -79,6 +79,7 @@ public: | ||
| 79 | virtual ~SrsServer(); | 79 | virtual ~SrsServer(); |
| 80 | public: | 80 | public: |
| 81 | virtual int initialize(); | 81 | virtual int initialize(); |
| 82 | + virtual int acquire_pid_file(); | ||
| 82 | virtual int listen(); | 83 | virtual int listen(); |
| 83 | virtual int cycle(); | 84 | virtual int cycle(); |
| 84 | virtual void remove(SrsConnection* conn); | 85 | virtual void remove(SrsConnection* conn); |
| @@ -92,6 +92,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -92,6 +92,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 92 | #define ERROR_SYSTEM_WAITPID 413 | 92 | #define ERROR_SYSTEM_WAITPID 413 |
| 93 | #define ERROR_SYSTEM_BANDWIDTH_KEY 414 | 93 | #define ERROR_SYSTEM_BANDWIDTH_KEY 414 |
| 94 | #define ERROR_SYSTEM_BANDWIDTH_DENIED 415 | 94 | #define ERROR_SYSTEM_BANDWIDTH_DENIED 415 |
| 95 | +#define ERROR_SYSTEM_PID_ACQUIRE 416 | ||
| 96 | +#define ERROR_SYSTEM_PID_ALREADY_RUNNING 417 | ||
| 97 | +#define ERROR_SYSTEM_PID_LOCK 418 | ||
| 98 | +#define ERROR_SYSTEM_PID_TRUNCATE_FILE 419 | ||
| 99 | +#define ERROR_SYSTEM_PID_WRITE_FILE 420 | ||
| 100 | +#define ERROR_SYSTEM_PID_GET_FILE_INFO 421 | ||
| 101 | +#define ERROR_SYSTEM_PID_SET_FILE_INFO 422 | ||
| 95 | 102 | ||
| 96 | // see librtmp. | 103 | // see librtmp. |
| 97 | // failed when open ssl create the dh | 104 | // failed when open ssl create the dh |
| @@ -91,6 +91,10 @@ int main(int argc, char** argv) | @@ -91,6 +91,10 @@ int main(int argc, char** argv) | ||
| 91 | 91 | ||
| 92 | // TODO: create log dir in _srs_config->get_log_dir() | 92 | // TODO: create log dir in _srs_config->get_log_dir() |
| 93 | 93 | ||
| 94 | + if ((ret = _srs_server->acquire_pid_file()) != ERROR_SUCCESS) { | ||
| 95 | + return ret; | ||
| 96 | + } | ||
| 97 | + | ||
| 94 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { | 98 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { |
| 95 | return ret; | 99 | return ret; |
| 96 | } | 100 | } |
-
请 注册 或 登录 后发表评论