int SrsConnection::cycle()
{
    int ret = ERROR_SUCCESS;
    
    _srs_context->generate_id();
    ip = srs_get_peer_ip(st_netfd_fileno(stfd));
    
    ret = do_cycle();
    
    // if socket io error, set to closed.
    if (srs_is_client_gracefully_close(ret)) {
        ret = ERROR_SOCKET_CLOSED;
    }
    
    // success.
    if (ret == ERROR_SUCCESS) {
        srs_trace("client finished.");
    }
    
    // client close peer.
    if (ret == ERROR_SOCKET_CLOSED) {
        srs_warn("client disconnect peer. ret=%d", ret);
    }
    
    // set loop to stop to quit.
    pthread->stop_loop();

    return ERROR_SUCCESS;
}
int SrsEdgeIngester::cycle()
{
    int ret = ERROR_SUCCESS;
    
    if ((ret = connect_server()) != ERROR_SUCCESS) {
        return ret;
    }
    srs_assert(client);

    client->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US);
    client->set_send_timeout(SRS_CONSTS_RTMP_SEND_TIMEOUT_US);

    SrsRequest* req = _req;
    
    if ((ret = client->handshake()) != ERROR_SUCCESS) {
        srs_error("handshake with server failed. ret=%d", ret);
        return ret;
    }
    if ((ret = client->connect_app(req->app, req->tcUrl, req)) != ERROR_SUCCESS) {
        srs_error("connect with server failed, tcUrl=%s. ret=%d", req->tcUrl.c_str(), ret);
        return ret;
    }
    if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {
        srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret);
        return ret;
    }
    
    if ((ret = client->play(req->stream, stream_id)) != ERROR_SUCCESS) {
        srs_error("connect with server failed, stream=%s, stream_id=%d. ret=%d", 
            req->stream.c_str(), stream_id, ret);
        return ret;
    }
    
    if ((ret = _source->on_publish()) != ERROR_SUCCESS) {
        srs_error("edge pull stream then publish to edge failed. ret=%d", ret);
        return ret;
    }
    
    if ((ret = _edge->on_ingest_play()) != ERROR_SUCCESS) {
        return ret;
    }
    
    ret = ingest();
    if (srs_is_client_gracefully_close(ret)) {
        srs_warn("origin disconnected, retry. ret=%d", ret);
        ret = ERROR_SUCCESS;
    }
    
    return ret;
}
int SrsEdgeIngester::ingest()
{
    int ret = ERROR_SUCCESS;
    
    client->set_recv_timeout(SRS_EDGE_INGESTER_TIMEOUT_US);
    
    SrsPithyPrint pithy_print(SRS_CONSTS_STAGE_EDGE);

    while (pthread->can_loop()) {
        // switch to other st-threads.
        st_usleep(0);
        
        pithy_print.elapse();
        
        // pithy print
        if (pithy_print.can_print()) {
            kbps->sample();
            srs_trace("<- "SRS_CONSTS_LOG_EDGE_PLAY
                " time=%"PRId64", okbps=%d,%d,%d, ikbps=%d,%d,%d", 
                pithy_print.age(),
                kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(),
                kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m());
        }

        // read from client.
        SrsMessage* msg = NULL;
        if ((ret = client->recv_message(&msg)) != ERROR_SUCCESS) {
            if (!srs_is_client_gracefully_close(ret)) {
                srs_error("pull origin server message failed. ret=%d", ret);
            }
            return ret;
        }
        srs_verbose("edge loop recv message. ret=%d", ret);
        
        srs_assert(msg);
        SrsAutoFree(SrsMessage, msg);
        
        if ((ret = process_publish_message(msg)) != ERROR_SUCCESS) {
            return ret;
        }
    }
    
    return ret;
}
 int expect_message(SrsMessage** pmsg, T** ppacket)
 {
     *pmsg = NULL;
     *ppacket = NULL;
     
     int ret = ERROR_SUCCESS;
     
     while (true) {
         SrsMessage* msg = NULL;
         if ((ret = recv_message(&msg)) != ERROR_SUCCESS) {
             if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {
                 srs_error("recv message failed. ret=%d", ret);
             }
             return ret;
         }
         srs_verbose("recv message success.");
         
         SrsPacket* packet = NULL;
         if ((ret = decode_message(msg, &packet)) != ERROR_SUCCESS) {
             srs_error("decode message failed. ret=%d", ret);
             srs_freep(msg);
             srs_freep(packet);
             return ret;
         }
         
         T* pkt = dynamic_cast<T*>(packet);
         if (!pkt) {
             srs_info("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).", 
                 msg->header.message_type, msg->header.payload_length,
                 msg->header.timestamp, msg->header.stream_id);
             srs_freep(msg);
             srs_freep(packet);
             continue;
         }
         
         *pmsg = msg;
         *ppacket = pkt;
         break;
     }
     
     return ret;
 }
Example #5
0
 void SrsThread::thread_cycle()
 {
     int ret = ERROR_SUCCESS;
     
     _srs_context->generate_id();
     srs_info("thread %s cycle start", _name);
     
     _cid = _srs_context->get_id();
     
     srs_assert(handler);
     handler->on_thread_start();
     
     // thread is running now.
     really_terminated = false;
     
     // wait for cid to ready, for parent thread to get the cid.
     while (!can_run && loop) {
         st_usleep(10 * 1000);
     }
     
     while (loop) {
         if ((ret = handler->on_before_cycle()) != ERROR_SUCCESS) {
             srs_warn("thread %s on before cycle failed, ignored and retry, ret=%d", _name, ret);
             goto failed;
         }
         srs_info("thread %s on before cycle success");
         
         if ((ret = handler->cycle()) != ERROR_SUCCESS) {
             if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) {
                 srs_warn("thread %s cycle failed, ignored and retry, ret=%d", _name, ret);
             }
             goto failed;
         }
         srs_info("thread %s cycle success", _name);
         
         if ((ret = handler->on_end_cycle()) != ERROR_SUCCESS) {
             srs_warn("thread %s on end cycle failed, ignored and retry, ret=%d", _name, ret);
             goto failed;
         }
         srs_info("thread %s on end cycle success", _name);
         
     failed:
         if (!loop) {
             break;
         }
         
         // to improve performance, donot sleep when interval is zero.
         // @see: https://github.com/ossrs/srs/issues/237
         if (cycle_interval_us != 0) {
             st_usleep(cycle_interval_us);
         }
     }
     
     // readly terminated now.
     really_terminated = true;
     
     // when thread terminated normally, also disposed.
     // we must set to disposed before the on_thread_stop, which may free the thread.
     // @see https://github.com/ossrs/srs/issues/546
     disposed = true;
     
     handler->on_thread_stop();
     srs_info("thread %s cycle finished", _name);
 }