mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-03-12 17:10:52 +08:00
- 增加客户端模式,支持主动拉流、推流: - addStreamProxy接口新增支持whep主动拉流,拉流地址目前只兼容zlm的whep url。 - addStreamPusherProxy接口新增支持whip主动推流,推流地址目前只兼容zlm的whip url。 - 以上推流url格式为webrtc[s]://server_host:server_port/app/stream_id?key=value, 内部会自动转换为http[s]://server_host:server_port/index/api/[whip/whep]?app=app&stream=stream_id&key=value。 - 增加WebRtc p2p 模式: - 增加 ICE FULL模式。 - 增加STUN/TURN 服务器。 - 增加websocket 信令。 - 增加P2P代理拉流。 --------- Co-authored-by: xia-chu <771730766@qq.com> Co-authored-by: mtdxc <mtdxc@126.com> Co-authored-by: cqm <cqm@97kid.com>
143 lines
4.8 KiB
C++
143 lines
4.8 KiB
C++
#ifndef MS_RTC_SCTP_ASSOCIATION_HPP
|
|
#define MS_RTC_SCTP_ASSOCIATION_HPP
|
|
|
|
#ifdef ENABLE_SCTP
|
|
#include <usrsctp.h>
|
|
#include "Util/Byte.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).
|
|
(toolkit::Byte::Get2Bytes(data, 0) == 5000) &&
|
|
(toolkit::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
|