diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp
index f836b1bc8..d84930a81 100644
--- a/trunk/src/app/srs_app_http_api.cpp
+++ b/trunk/src/app/srs_app_http_api.cpp
@@ -26,6 +26,7 @@
 #include <sstream>
 #include <stdlib.h>
 #include <signal.h>
+#include <unistd.h>
 using namespace std;
 
 #include <srs_kernel_log.hpp>
@@ -994,7 +995,7 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str
     local_sdp.addrtype_        = "IP4";
     local_sdp.unicast_address_ = "0.0.0.0";
 
-    local_sdp.session_name_ = "live_play_session";
+    local_sdp.session_name_ = "SRSPlaySession";
 
     local_sdp.msid_semantic_ = "WMS";
     local_sdp.msids_.push_back(app + "/" + stream);
@@ -1088,6 +1089,10 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str
         local_media_desc.rtcp_mux_ = true;
         local_media_desc.rtcp_rsize_ = true;
 
+        if (!ssrc_num) {
+            ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid();
+        }
+
         if (local_media_desc.sendonly_ || local_media_desc.sendrecv_) {
             SrsSSRCInfo ssrc_info;
             ssrc_info.ssrc_ = ++ssrc_num;
@@ -1298,7 +1303,7 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(const std::string& app, const std::
     local_sdp.addrtype_        = "IP4";
     local_sdp.unicast_address_ = "0.0.0.0";
 
-    local_sdp.session_name_ = "live_publish_session";
+    local_sdp.session_name_ = "SRSPublishSession";
 
     local_sdp.msid_semantic_ = "WMS";
     local_sdp.msids_.push_back(app + "/" + stream);
@@ -1385,23 +1390,13 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(const std::string& app, const std::
         }
 
         local_sdp.media_descs_.back().session_info_.ice_options_ = "trickle";
-    
-        if (remote_media_desc.sendonly_) {
-            local_media_desc.recvonly_ = true;
-        } else if (remote_media_desc.recvonly_) {
-            local_media_desc.sendonly_ = true;
-        } else if (remote_media_desc.sendrecv_) {
-            local_media_desc.sendrecv_ = true;
-        }
 
         local_media_desc.rtcp_mux_ = true;
 
-        if (local_media_desc.recvonly_ || local_media_desc.sendrecv_) {
-            SrsSSRCInfo ssrc_info;
-            ssrc_info.ssrc_ = ++ssrc_num;
-            ssrc_info.cname_ = "test_sdp_cname";
-            local_media_desc.ssrc_infos_.push_back(ssrc_info);
-        }
+        // For publisher, we are always sendonly.
+        local_media_desc.sendonly_ = false;
+        local_media_desc.recvonly_ = true;
+        local_media_desc.sendrecv_ = false;
     }
 
     return err;
diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp
index 5c58a2667..d2212cff9 100644
--- a/trunk/src/app/srs_app_rtc_conn.cpp
+++ b/trunk/src/app/srs_app_rtc_conn.cpp
@@ -749,6 +749,7 @@ srs_error_t SrsRtcSenderThread::cycle()
         ::getpid(), source->source_id(), rtc_session->encrypt, realtime, srsu2msi(mw_sleep), mw_msgs);
 
     // For RTC, notify the source to fetch keyframe for this client.
+    // TODO: FIXME: Should triggle by PLI from client.
     source->request_keyframe();
 
     SrsMessageArray msgs(SRS_PERF_MW_MSGS);
@@ -2240,7 +2241,7 @@ srs_error_t SrsRtcPublisher::notify(int type, srs_utime_t interval, srs_utime_t
     return err;
 }
 
-SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string& un, int context_id)
+SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id)
 {
     username = un;
     req = r->copy();
@@ -2250,6 +2251,7 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string&
     source = NULL;
     publisher = NULL;
     sender = NULL;
+    is_publisher_ = is_publisher;
     sendonly_skt = NULL;
     rtc_server = s;
     dtls_session = new SrsDtlsSession(this);
@@ -2522,17 +2524,14 @@ srs_error_t SrsRtcSession::on_connection_established()
 {
     srs_error_t err = srs_success;
 
-    srs_trace("rtc session=%s, to=%dms connection established", id().c_str(), srsu2msi(sessionStunTimeout));
+    srs_trace("RTC %s session=%s, to=%dms connection established", (is_publisher_? "Publisher":"Subscriber"),
+        id().c_str(), srsu2msi(sessionStunTimeout));
 
-    if (!local_sdp.media_descs_.empty() &&
-        (local_sdp.media_descs_.back().recvonly_ || local_sdp.media_descs_.back().sendrecv_)) {
+    if (is_publisher_) {
         if ((err = start_publish()) != srs_success) {
             return srs_error_wrap(err, "start publish");
         }
-    }
-
-    if (!local_sdp.media_descs_.empty() &&
-        (local_sdp.media_descs_.back().sendonly_ || local_sdp.media_descs_.back().sendrecv_)) {
+    } else {
         if ((err = start_play()) != srs_success) {
             return srs_error_wrap(err, "start play");
         }
@@ -2580,7 +2579,6 @@ srs_error_t SrsRtcSession::start_publish()
 
     srs_freep(publisher);
     publisher = new SrsRtcPublisher(this);
-    publisher->request_keyframe();
 
     uint32_t video_ssrc = 0;
     uint32_t audio_ssrc = 0;
@@ -3361,7 +3359,7 @@ srs_error_t SrsRtcServer::create_rtc_session(
     }
 
     int cid = _srs_context->get_id();
-    SrsRtcSession* session = new SrsRtcSession(this, req, username, cid);
+    SrsRtcSession* session = new SrsRtcSession(this, req, publish, username, cid);
     if ((err = session->initialize()) != srs_success) {
         srs_freep(session);
         return srs_error_wrap(err, "init");
diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp
index 7d1abae90..0623e56ea 100644
--- a/trunk/src/app/srs_app_rtc_conn.hpp
+++ b/trunk/src/app/srs_app_rtc_conn.hpp
@@ -311,6 +311,7 @@ private:
     SrsDtlsSession* dtls_session;
     SrsRtcSenderThread* sender;
     SrsRtcPublisher* publisher;
+    bool is_publisher_;
 private:
     SrsUdpMuxSocket* sendonly_skt;
     std::string username;
@@ -336,7 +337,7 @@ private:
     sockaddr_in* blackhole_addr;
     srs_netfd_t blackhole_stfd;
 public:
-    SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string& un, int context_id);
+    SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id);
     virtual ~SrsRtcSession();
 public:
     SrsSdp* get_local_sdp();