WebRtcSession.cpp 3.26 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
 *
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
 *
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
 */

#include "WebRtcSession.h"
#include "Util/util.h"

夏楚 committed
14
using namespace std;
15 16

namespace mediakit {
夏楚 committed
17

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
static string getUserName(const Buffer::Ptr &buffer) {
    auto buf = buffer->data();
    auto len = buffer->size();
    if (!RTC::StunPacket::IsStun((const uint8_t *) buf, len)) {
        return "";
    }
    std::unique_ptr<RTC::StunPacket> packet(RTC::StunPacket::Parse((const uint8_t *) buf, len));
    if (!packet) {
        return "";
    }
    if (packet->GetClass() != RTC::StunPacket::Class::REQUEST ||
        packet->GetMethod() != RTC::StunPacket::Method::BINDING) {
        return "";
    }
    //收到binding request请求
    auto vec = split(packet->GetUsername(), ":");
    return vec[0];
}

ziyue committed
37
EventPoller::Ptr WebRtcSession::queryPoller(const Buffer::Ptr &buffer) {
38 39 40 41
    auto user_name = getUserName(buffer);
    if (user_name.empty()) {
        return nullptr;
    }
ziyue committed
42
    auto ret = WebRtcTransportManager::Instance().getItem(user_name);
43 44 45
    return ret ? ret->getPoller() : nullptr;
}

ziyue committed
46 47 48 49
////////////////////////////////////////////////////////////////////////////////

WebRtcSession::WebRtcSession(const Socket::Ptr &sock) : UdpSession(sock) {
    socklen_t addr_len = sizeof(_peer_addr);
xiongziliang committed
50
    getpeername(sock->rawFD(), (struct sockaddr *)&_peer_addr, &addr_len);
ziyue committed
51 52 53 54 55 56
}

WebRtcSession::~WebRtcSession() {
    InfoP(this);
}

57
void WebRtcSession::onRecv(const Buffer::Ptr &buffer) {
ziyue committed
58 59 60
    if (_find_transport) {
        //只允许寻找一次transport
        _find_transport = false;
61
        auto user_name = getUserName(buffer);
ziyue committed
62
        auto transport = WebRtcTransportManager::Instance().getItem(user_name);
63 64 65
        CHECK(transport && transport->getPoller()->isCurrentThread());
        transport->setSession(shared_from_this());
        _transport = std::move(transport);
66
        InfoP(this);
67
    }
68
    _ticker.resetTime();
ziyue committed
69
    CHECK(_transport);
xiongziliang committed
70
    _transport->inputSockData(buffer->data(), buffer->size(), (struct sockaddr *)&_peer_addr);
71 72 73
}

void WebRtcSession::onError(const SockException &err) {
74 75 76 77
    //udp链接超时,但是rtc链接不一定超时,因为可能存在udp链接迁移的情况
    //在udp链接迁移时,新的WebRtcSession对象将接管WebRtcTransport对象的生命周期
    //本WebRtcSession对象将在超时后自动销毁
    WarnP(this) << err.what();
ziyue committed
78

ziyue committed
79 80 81
    if (!_transport) {
        return;
    }
ziyue committed
82
    auto transport = std::move(_transport);
83
    getPoller()->async([transport] {
ziyue committed
84 85
        //延时减引用,防止使用transport对象时,销毁对象
    }, false);
86 87 88
}

void WebRtcSession::onManager() {
89
    GET_CONFIG(float, timeoutSec, Rtc::kTimeOutSec);
90 91 92 93 94 95 96 97
    if (!_transport && _ticker.createdTime() > timeoutSec * 1000) {
        shutdown(SockException(Err_timeout, "illegal webrtc connection"));
        return;
    }
    if (_ticker.elapsedTime() > timeoutSec * 1000) {
        shutdown(SockException(Err_timeout, "webrtc connection timeout"));
        return;
    }
98
}
99

100
}// namespace mediakit
101

102