mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-21 18:24:24 +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)
|
||||
|
||||
#默认链接jemalloc库避免内存碎片
|
||||
find_package(JEMALLOC QUIET)
|
||||
if (JEMALLOC_FOUND)
|
||||
message(STATUS "found library:\"${JEMALLOC_LIBRARIES}\"")
|
||||
include_directories(${JEMALLOC_INCLUDE_DIR})
|
||||
list(APPEND LINK_LIB_LIST ${JEMALLOC_LIBRARIES})
|
||||
endif ()
|
||||
##默认链接jemalloc库避免内存碎片
|
||||
#find_package(JEMALLOC QUIET)
|
||||
#if (JEMALLOC_FOUND)
|
||||
# message(STATUS "found library:\"${JEMALLOC_LIBRARIES}\"")
|
||||
# include_directories(${JEMALLOC_INCLUDE_DIR})
|
||||
# list(APPEND LINK_LIB_LIST ${JEMALLOC_LIBRARIES})
|
||||
#endif ()
|
||||
|
||||
#查找openssl是否安装
|
||||
find_package(OpenSSL QUIET)
|
||||
@ -351,6 +351,15 @@ if (ENABLE_WEBRTC)
|
||||
add_library(webrtc ${SRC_WEBRTC_LIST})
|
||||
list(APPEND LINK_LIB_LIST 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 ()
|
||||
set(ENABLE_WEBRTC off)
|
||||
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(){
|
||||
#ifdef ENABLE_SCTP
|
||||
_sctp = nullptr;
|
||||
#endif
|
||||
_dtls_transport = nullptr;
|
||||
_ice_server = nullptr;
|
||||
}
|
||||
@ -112,6 +115,10 @@ void WebRtcTransport::OnDtlsTransportConnected(
|
||||
InfoL;
|
||||
_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);
|
||||
#ifdef ENABLE_SCTP
|
||||
_sctp = std::make_shared<RTC::SctpAssociationImp>(getPoller(), this, 128, 128, 262144, true);
|
||||
_sctp->TransportConnected();
|
||||
#endif
|
||||
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) {
|
||||
#ifdef ENABLE_SCTP
|
||||
_sctp->ProcessSctpData(data, len);
|
||||
#else
|
||||
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){
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "Nack.h"
|
||||
#include "Network/Session.h"
|
||||
#include "TwccContext.h"
|
||||
#include "SctpAssociation.hpp"
|
||||
|
||||
//RTC配置项目
|
||||
namespace RTC {
|
||||
@ -56,7 +57,11 @@ private:
|
||||
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:
|
||||
using Ptr = std::shared_ptr<WebRtcTransport>;
|
||||
WebRtcTransport(const EventPoller::Ptr &poller);
|
||||
@ -128,6 +133,16 @@ protected:
|
||||
void OnIceServerCompleted(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:
|
||||
virtual void onStartWebRTC() = 0;
|
||||
virtual void onRtcConfigure(RtcConfigure &configure) const;
|
||||
@ -163,6 +178,10 @@ private:
|
||||
Ticker _ticker;
|
||||
//循环池
|
||||
ResourcePool<BufferRaw> _packet_pool;
|
||||
|
||||
#ifdef ENABLE_SCTP
|
||||
RTC::SctpAssociationImp::Ptr _sctp;
|
||||
#endif
|
||||
};
|
||||
|
||||
class RtpChannel;
|
||||
|
Loading…
Reference in New Issue
Block a user