mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 10:40:05 +08:00
新增webrtc datachannel功能: #1216
This commit is contained in:
parent
200a193c04
commit
fb003714e9
@ -176,13 +176,13 @@ endif ()
|
|||||||
|
|
||||||
set(LINK_LIB_LIST zlmediakit zltoolkit)
|
set(LINK_LIB_LIST zlmediakit zltoolkit)
|
||||||
|
|
||||||
#默认链接jemalloc库避免内存碎片
|
##默认链接jemalloc库避免内存碎片
|
||||||
find_package(JEMALLOC QUIET)
|
#find_package(JEMALLOC QUIET)
|
||||||
if (JEMALLOC_FOUND)
|
#if (JEMALLOC_FOUND)
|
||||||
message(STATUS "found library:\"${JEMALLOC_LIBRARIES}\"")
|
# message(STATUS "found library:\"${JEMALLOC_LIBRARIES}\"")
|
||||||
include_directories(${JEMALLOC_INCLUDE_DIR})
|
# include_directories(${JEMALLOC_INCLUDE_DIR})
|
||||||
list(APPEND LINK_LIB_LIST ${JEMALLOC_LIBRARIES})
|
# list(APPEND LINK_LIB_LIST ${JEMALLOC_LIBRARIES})
|
||||||
endif ()
|
#endif ()
|
||||||
|
|
||||||
#查找openssl是否安装
|
#查找openssl是否安装
|
||||||
find_package(OpenSSL QUIET)
|
find_package(OpenSSL QUIET)
|
||||||
@ -351,6 +351,15 @@ if (ENABLE_WEBRTC)
|
|||||||
add_library(webrtc ${SRC_WEBRTC_LIST})
|
add_library(webrtc ${SRC_WEBRTC_LIST})
|
||||||
list(APPEND LINK_LIB_LIST webrtc)
|
list(APPEND LINK_LIB_LIST webrtc)
|
||||||
message(STATUS "webrtc功能已开启")
|
message(STATUS "webrtc功能已开启")
|
||||||
|
|
||||||
|
find_package(SCTP QUIET)
|
||||||
|
if (SCTP_FOUND)
|
||||||
|
message(STATUS "found library:${SCTP_INCLUDE_DIRS} ${SCTP_LIBRARIES}")
|
||||||
|
include_directories(${SCTP_INCLUDE_DIRS})
|
||||||
|
list(APPEND LINK_LIB_LIST ${SCTP_LIBRARIES})
|
||||||
|
add_definitions(-DENABLE_SCTP)
|
||||||
|
message(STATUS "webrtc datachannel功能已打开")
|
||||||
|
endif ()
|
||||||
else ()
|
else ()
|
||||||
set(ENABLE_WEBRTC off)
|
set(ENABLE_WEBRTC off)
|
||||||
message(WARNING "srtp未找到, webrtc相关功能打开失败")
|
message(WARNING "srtp未找到, webrtc相关功能打开失败")
|
||||||
|
24
cmake/FindSCTP.cmake
Normal file
24
cmake/FindSCTP.cmake
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# - Try to find sctp
|
||||||
|
#
|
||||||
|
# Once done this will define
|
||||||
|
# SCTP_FOUND - System has mbedtls
|
||||||
|
# SCTP_INCLUDE_DIRS - The mbedtls include directories
|
||||||
|
# SCTP_LIBRARIES - The mbedtls library
|
||||||
|
|
||||||
|
|
||||||
|
#find Mbedtls
|
||||||
|
FIND_PATH(
|
||||||
|
SCTP_INCLUDE_DIRS
|
||||||
|
NAMES usrsctp.h
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(
|
||||||
|
SCTP_LIBRARIES
|
||||||
|
NAMES usrsctp
|
||||||
|
)
|
||||||
|
|
||||||
|
message(STATUS "SCTP LIBRARIES: " ${SCTP_LIBRARIES})
|
||||||
|
message(STATUS "SCTP INCLUDE DIRS: " ${SCTP_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SCTP DEFAULT_MSG SCTP_LIBRARIES SCTP_INCLUDE_DIRS)
|
1006
webrtc/SctpAssociation.cpp
Normal file
1006
webrtc/SctpAssociation.cpp
Normal file
File diff suppressed because it is too large
Load Diff
142
webrtc/SctpAssociation.hpp
Normal file
142
webrtc/SctpAssociation.hpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#ifndef MS_RTC_SCTP_ASSOCIATION_HPP
|
||||||
|
#define MS_RTC_SCTP_ASSOCIATION_HPP
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
#include <usrsctp.h>
|
||||||
|
#include "Utils.hpp"
|
||||||
|
#include "Poller/EventPoller.h"
|
||||||
|
|
||||||
|
namespace RTC
|
||||||
|
{
|
||||||
|
class SctpEnv;
|
||||||
|
class SctpStreamParameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint16_t streamId{ 0u };
|
||||||
|
bool ordered{ true };
|
||||||
|
uint16_t maxPacketLifeTime{ 0u };
|
||||||
|
uint16_t maxRetransmits{ 0u };
|
||||||
|
};
|
||||||
|
|
||||||
|
class SctpAssociation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class SctpState
|
||||||
|
{
|
||||||
|
NEW = 1,
|
||||||
|
CONNECTING,
|
||||||
|
CONNECTED,
|
||||||
|
FAILED,
|
||||||
|
CLOSED
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class StreamDirection
|
||||||
|
{
|
||||||
|
INCOMING = 1,
|
||||||
|
OUTGOING
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
class Listener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnSctpAssociationConnecting(RTC::SctpAssociation* sctpAssociation) = 0;
|
||||||
|
virtual void OnSctpAssociationConnected(RTC::SctpAssociation* sctpAssociation) = 0;
|
||||||
|
virtual void OnSctpAssociationFailed(RTC::SctpAssociation* sctpAssociation) = 0;
|
||||||
|
virtual void OnSctpAssociationClosed(RTC::SctpAssociation* sctpAssociation) = 0;
|
||||||
|
virtual void OnSctpAssociationSendData(
|
||||||
|
RTC::SctpAssociation* sctpAssociation, const uint8_t* data, size_t len) = 0;
|
||||||
|
virtual void OnSctpAssociationMessageReceived(
|
||||||
|
RTC::SctpAssociation* sctpAssociation,
|
||||||
|
uint16_t streamId,
|
||||||
|
uint32_t ppid,
|
||||||
|
const uint8_t* msg,
|
||||||
|
size_t len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool IsSctp(const uint8_t* data, size_t len)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
return (
|
||||||
|
(len >= 12) &&
|
||||||
|
// Must have Source Port Number and Destination Port Number set to 5000 (hack).
|
||||||
|
(Utils::Byte::Get2Bytes(data, 0) == 5000) &&
|
||||||
|
(Utils::Byte::Get2Bytes(data, 2) == 5000)
|
||||||
|
);
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
SctpAssociation(
|
||||||
|
Listener* listener, uint16_t os, uint16_t mis, size_t maxSctpMessageSize, bool isDataChannel);
|
||||||
|
virtual ~SctpAssociation();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void TransportConnected();
|
||||||
|
size_t GetMaxSctpMessageSize() const
|
||||||
|
{
|
||||||
|
return this->maxSctpMessageSize;
|
||||||
|
}
|
||||||
|
SctpState GetState() const
|
||||||
|
{
|
||||||
|
return this->state;
|
||||||
|
}
|
||||||
|
void ProcessSctpData(const uint8_t* data, size_t len);
|
||||||
|
void SendSctpMessage(const RTC::SctpStreamParameters ¶ms, uint32_t ppid, const uint8_t* msg, size_t len);
|
||||||
|
void HandleDataConsumer(const RTC::SctpStreamParameters ¶ms);
|
||||||
|
void DataProducerClosed(const RTC::SctpStreamParameters ¶ms);
|
||||||
|
void DataConsumerClosed(const RTC::SctpStreamParameters ¶ms);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ResetSctpStream(uint16_t streamId, StreamDirection);
|
||||||
|
void AddOutgoingStreams(bool force = false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Callbacks fired by usrsctp events. */
|
||||||
|
virtual void OnUsrSctpSendSctpData(void* buffer, size_t len);
|
||||||
|
virtual void OnUsrSctpReceiveSctpData(uint16_t streamId, uint16_t ssn, uint32_t ppid, int flags, const uint8_t* data, size_t len);
|
||||||
|
virtual void OnUsrSctpReceiveSctpNotification(union sctp_notification* notification, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Passed by argument.
|
||||||
|
Listener* listener{ nullptr };
|
||||||
|
uint16_t os{ 1024u };
|
||||||
|
uint16_t mis{ 1024u };
|
||||||
|
size_t maxSctpMessageSize{ 262144u };
|
||||||
|
bool isDataChannel{ false };
|
||||||
|
// Allocated by this.
|
||||||
|
uint8_t* messageBuffer{ nullptr };
|
||||||
|
// Others.
|
||||||
|
SctpState state{ SctpState::NEW };
|
||||||
|
struct socket* socket{ nullptr };
|
||||||
|
uint16_t desiredOs{ 0u };
|
||||||
|
size_t messageBufferLen{ 0u };
|
||||||
|
uint16_t lastSsnReceived{ 0u }; // Valid for us since no SCTP I-DATA support.
|
||||||
|
std::shared_ptr<SctpEnv> _env;
|
||||||
|
};
|
||||||
|
|
||||||
|
//保证线程安全
|
||||||
|
class SctpAssociationImp : public SctpAssociation, public std::enable_shared_from_this<SctpAssociationImp>{
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<SctpAssociationImp>;
|
||||||
|
template<typename ... ARGS>
|
||||||
|
SctpAssociationImp(toolkit::EventPoller::Ptr poller, ARGS &&...args) : SctpAssociation(std::forward<ARGS>(args)...) {
|
||||||
|
_poller = std::move(poller);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SctpAssociationImp() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnUsrSctpSendSctpData(void* buffer, size_t len) override;
|
||||||
|
void OnUsrSctpReceiveSctpData(uint16_t streamId, uint16_t ssn, uint32_t ppid, int flags, const uint8_t* data, size_t len) override;
|
||||||
|
void OnUsrSctpReceiveSctpNotification(union sctp_notification* notification, size_t len) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
toolkit::EventPoller::Ptr _poller;
|
||||||
|
};
|
||||||
|
} // namespace RTC
|
||||||
|
|
||||||
|
#endif //ENABLE_SCTP
|
||||||
|
#endif //MS_RTC_SCTP_ASSOCIATION_HPP
|
@ -60,6 +60,9 @@ void WebRtcTransport::onCreate(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransport::onDestory(){
|
void WebRtcTransport::onDestory(){
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
_sctp = nullptr;
|
||||||
|
#endif
|
||||||
_dtls_transport = nullptr;
|
_dtls_transport = nullptr;
|
||||||
_ice_server = nullptr;
|
_ice_server = nullptr;
|
||||||
}
|
}
|
||||||
@ -112,6 +115,10 @@ void WebRtcTransport::OnDtlsTransportConnected(
|
|||||||
InfoL;
|
InfoL;
|
||||||
_srtp_session_send = std::make_shared<RTC::SrtpSession>(RTC::SrtpSession::Type::OUTBOUND, srtpCryptoSuite, srtpLocalKey, srtpLocalKeyLen);
|
_srtp_session_send = std::make_shared<RTC::SrtpSession>(RTC::SrtpSession::Type::OUTBOUND, srtpCryptoSuite, srtpLocalKey, srtpLocalKeyLen);
|
||||||
_srtp_session_recv = std::make_shared<RTC::SrtpSession>(RTC::SrtpSession::Type::INBOUND, srtpCryptoSuite, srtpRemoteKey, srtpRemoteKeyLen);
|
_srtp_session_recv = std::make_shared<RTC::SrtpSession>(RTC::SrtpSession::Type::INBOUND, srtpCryptoSuite, srtpRemoteKey, srtpRemoteKeyLen);
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
_sctp = std::make_shared<RTC::SctpAssociationImp>(getPoller(), this, 128, 128, 262144, true);
|
||||||
|
_sctp->TransportConnected();
|
||||||
|
#endif
|
||||||
onStartWebRTC();
|
onStartWebRTC();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +141,44 @@ void WebRtcTransport::OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) {
|
void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) {
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
_sctp->ProcessSctpData(data, len);
|
||||||
|
#else
|
||||||
InfoL << hexdump(data, len);
|
InfoL << hexdump(data, len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
void WebRtcTransport::OnSctpAssociationConnecting(RTC::SctpAssociation* sctpAssociation) {
|
||||||
|
TraceL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::OnSctpAssociationConnected(RTC::SctpAssociation* sctpAssociation) {
|
||||||
|
InfoL << getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::OnSctpAssociationFailed(RTC::SctpAssociation* sctpAssociation) {
|
||||||
|
WarnL << getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::OnSctpAssociationClosed(RTC::SctpAssociation* sctpAssociation) {
|
||||||
|
InfoL << getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::OnSctpAssociationSendData(RTC::SctpAssociation* sctpAssociation, const uint8_t* data, size_t len) {
|
||||||
|
_dtls_transport->SendApplicationData(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::OnSctpAssociationMessageReceived(RTC::SctpAssociation *sctpAssociation, uint16_t streamId,
|
||||||
|
uint32_t ppid, const uint8_t *msg, size_t len) {
|
||||||
|
InfoL << getIdentifier() << " " << streamId << " " << ppid << " " << len << " " << string((char *)msg, len);
|
||||||
|
RTC::SctpStreamParameters params;
|
||||||
|
params.streamId = streamId;
|
||||||
|
//回显数据
|
||||||
|
_sctp->SendSctpMessage(params, ppid, msg, len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void WebRtcTransport::sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple){
|
void WebRtcTransport::sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple){
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "Nack.h"
|
#include "Nack.h"
|
||||||
#include "Network/Session.h"
|
#include "Network/Session.h"
|
||||||
#include "TwccContext.h"
|
#include "TwccContext.h"
|
||||||
|
#include "SctpAssociation.hpp"
|
||||||
|
|
||||||
//RTC配置项目
|
//RTC配置项目
|
||||||
namespace RTC {
|
namespace RTC {
|
||||||
@ -56,7 +57,11 @@ private:
|
|||||||
SockException _ex;
|
SockException _ex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebRtcTransport : public WebRtcInterface, public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener, public std::enable_shared_from_this<WebRtcTransport> {
|
class WebRtcTransport : public WebRtcInterface, public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener, public std::enable_shared_from_this<WebRtcTransport>
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
, public RTC::SctpAssociation::Listener
|
||||||
|
#endif
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<WebRtcTransport>;
|
using Ptr = std::shared_ptr<WebRtcTransport>;
|
||||||
WebRtcTransport(const EventPoller::Ptr &poller);
|
WebRtcTransport(const EventPoller::Ptr &poller);
|
||||||
@ -128,6 +133,16 @@ protected:
|
|||||||
void OnIceServerCompleted(const RTC::IceServer *iceServer) override;
|
void OnIceServerCompleted(const RTC::IceServer *iceServer) override;
|
||||||
void OnIceServerDisconnected(const RTC::IceServer *iceServer) override;
|
void OnIceServerDisconnected(const RTC::IceServer *iceServer) override;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
void OnSctpAssociationConnecting(RTC::SctpAssociation* sctpAssociation) override;
|
||||||
|
void OnSctpAssociationConnected(RTC::SctpAssociation* sctpAssociation) override;
|
||||||
|
void OnSctpAssociationFailed(RTC::SctpAssociation* sctpAssociation) override;
|
||||||
|
void OnSctpAssociationClosed(RTC::SctpAssociation* sctpAssociation) override;
|
||||||
|
void OnSctpAssociationSendData(RTC::SctpAssociation* sctpAssociation, const uint8_t* data, size_t len) override;
|
||||||
|
void OnSctpAssociationMessageReceived(RTC::SctpAssociation *sctpAssociation, uint16_t streamId, uint32_t ppid,
|
||||||
|
const uint8_t *msg, size_t len) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onStartWebRTC() = 0;
|
virtual void onStartWebRTC() = 0;
|
||||||
virtual void onRtcConfigure(RtcConfigure &configure) const;
|
virtual void onRtcConfigure(RtcConfigure &configure) const;
|
||||||
@ -163,6 +178,10 @@ private:
|
|||||||
Ticker _ticker;
|
Ticker _ticker;
|
||||||
//循环池
|
//循环池
|
||||||
ResourcePool<BufferRaw> _packet_pool;
|
ResourcePool<BufferRaw> _packet_pool;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCTP
|
||||||
|
RTC::SctpAssociationImp::Ptr _sctp;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtpChannel;
|
class RtpChannel;
|
||||||
|
Loading…
Reference in New Issue
Block a user