浏览代码

Fixed DataChannel creation when SCTP transport is not ready

Paul-Louis Ageneau 6 年之前
父节点
当前提交
ac8fd08018
共有 3 个文件被更改,包括 36 次插入30 次删除
  1. 24 16
      src/datachannel.cpp
  2. 6 7
      src/datachannel.hpp
  3. 6 7
      src/peerconnection.cpp

+ 24 - 16
src/datachannel.cpp

@@ -51,16 +51,13 @@ struct CloseMessage {
 	uint8_t type = MESSAGE_CLOSE;
 };
 
-DataChannel::DataChannel(shared_ptr<SctpTransport> sctpTransport, unsigned int streamId)
-    : mSctpTransport(sctpTransport), mStreamId(streamId) {}
-
-DataChannel::DataChannel(shared_ptr<SctpTransport> sctpTransport, unsigned int streamId,
-                         string label, string protocol, Reliability reliability)
-    : DataChannel(sctpTransport, streamId) {
-	mLabel = std::move(label);
-	mProtocol = std::move(protocol);
-	mReliability = std::make_shared<Reliability>(std::move(reliability));
-}
+DataChannel::DataChannel(unsigned int stream, string label, string protocol,
+                         Reliability reliability)
+    : mStream(stream), mLabel(std::move(label)), mProtocol(std::move(protocol)),
+      mReliability(std::make_shared<Reliability>(std::move(reliability))) {}
+
+DataChannel::DataChannel(unsigned int stream, shared_ptr<SctpTransport> sctpTransport)
+    : mStream(stream), mSctpTransport(sctpTransport) {}
 
 DataChannel::~DataChannel() { close(); }
 
@@ -68,25 +65,34 @@ void DataChannel::close() {
 	mIsOpen = false;
 	if (!mIsClosed) {
 		mIsClosed = true;
-		mSctpTransport->reset(mStreamId);
+		if (mSctpTransport)
+			mSctpTransport->reset(mStream);
 	}
 }
 
 void DataChannel::send(const std::variant<binary, string> &data) {
+	if (!mSctpTransport)
+		return;
+
 	std::visit(
 	    [this](const auto &d) {
 		    using T = std::decay_t<decltype(d)>;
 		    constexpr auto type = std::is_same_v<T, string> ? Message::String : Message::Binary;
 		    auto *b = reinterpret_cast<const byte *>(d.data());
-		    mSctpTransport->send(make_message(b, b + d.size(), type, mStreamId, mReliability));
+		    mSctpTransport->send(make_message(b, b + d.size(), type, mStream, mReliability));
 	    },
 	    data);
 }
 
 void DataChannel::send(const byte *data, size_t size) {
-	mSctpTransport->send(make_message(data, data + size, Message::Binary, mStreamId));
+	if (!mSctpTransport)
+		return;
+
+	mSctpTransport->send(make_message(data, data + size, Message::Binary, mStream));
 }
 
+unsigned int DataChannel::stream() const { return mStream; }
+
 string DataChannel::label() const { return mLabel; }
 
 string DataChannel::protocol() const { return mProtocol; }
@@ -97,7 +103,9 @@ bool DataChannel::isOpen(void) const { return mIsOpen; }
 
 bool DataChannel::isClosed(void) const { return mIsClosed; }
 
-void DataChannel::open() {
+void DataChannel::open(shared_ptr<SctpTransport> sctpTransport) {
+	mSctpTransport = sctpTransport;
+
 	uint8_t channelType = static_cast<uint8_t>(mReliability->type);
 	if (mReliability->unordered)
 		channelType &= 0x80;
@@ -123,7 +131,7 @@ void DataChannel::open() {
 	std::copy(mLabel.begin(), mLabel.end(), end);
 	std::copy(mProtocol.begin(), mProtocol.end(), end + mLabel.size());
 
-	mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStreamId));
+	mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStream));
 }
 
 void DataChannel::incoming(message_ptr message) {
@@ -203,7 +211,7 @@ void DataChannel::processOpenMessage(message_ptr message) {
 	auto &ack = *reinterpret_cast<AckMessage *>(buffer.data());
 	ack.type = MESSAGE_ACK;
 
-	mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStreamId));
+	mSctpTransport->send(make_message(buffer.begin(), buffer.end(), Message::Control, mStream));
 
 	triggerOpen();
 }

+ 6 - 7
src/datachannel.hpp

@@ -35,15 +35,15 @@ class PeerConnection;
 
 class DataChannel : public Channel {
 public:
-	DataChannel(std::shared_ptr<SctpTransport> sctpTransport, unsigned int streamId);
-	DataChannel(std::shared_ptr<SctpTransport> sctpTransport, unsigned int streamId, string label,
-	            string protocol, Reliability reliability);
+	DataChannel(unsigned int stream_, string label_, string protocol_, Reliability reliability_);
+	DataChannel(unsigned int stream, std::shared_ptr<SctpTransport> sctpTransport);
 	~DataChannel();
 
 	void close(void);
 	void send(const std::variant<binary, string> &data);
 	void send(const byte *data, size_t size);
 
+	unsigned int stream() const;
 	string label() const;
 	string protocol() const;
 	Reliability reliability() const;
@@ -52,13 +52,12 @@ public:
 	bool isClosed(void) const;
 
 private:
-	void open();
+	void open(std::shared_ptr<SctpTransport> sctpTransport);
 	void incoming(message_ptr message);
 	void processOpenMessage(message_ptr message);
 
-	const std::shared_ptr<SctpTransport> mSctpTransport;
-	const unsigned int mStreamId;
-
+	const unsigned int mStream;
+	std::shared_ptr<SctpTransport> mSctpTransport;
 	string mLabel;
 	string mProtocol;
 	std::shared_ptr<Reliability> mReliability;

+ 6 - 7
src/peerconnection.cpp

@@ -66,18 +66,17 @@ shared_ptr<DataChannel> PeerConnection::createDataChannel(const string &label,
 	auto seed = std::chrono::system_clock::now().time_since_epoch().count();
 	std::default_random_engine generator(seed);
 	std::uniform_int_distribution<uint16_t> uniform;
-	uint16_t streamId = uniform(generator);
+	uint16_t stream = uniform(generator);
 
-	auto channel =
-	    std::make_shared<DataChannel>(mSctpTransport, streamId, label, protocol, reliability);
-	mDataChannels[streamId] = channel;
+	auto channel = std::make_shared<DataChannel>(stream, label, protocol, reliability);
+	mDataChannels.insert(std::make_pair(stream, channel));
 
 	if (!mIceTransport) {
 		initIceTransport(Description::Role::Active);
 		triggerLocalDescription();
 		mIceTransport->gatherLocalCandidates();
 	} else if (mSctpTransport && mSctpTransport->isReady()) {
-		channel->open();
+		channel->open(mSctpTransport);
 	}
 	return channel;
 }
@@ -123,7 +122,7 @@ void PeerConnection::forwardMessage(message_ptr message) {
 	if (auto it = mDataChannels.find(message->stream); it != mDataChannels.end()) {
 		channel = it->second;
 	} else {
-		channel = std::make_shared<DataChannel>(mSctpTransport, message->stream);
+		channel = std::make_shared<DataChannel>(message->stream, mSctpTransport);
 		channel->onOpen(std::bind(&PeerConnection::triggerDataChannel, this, channel));
 		mDataChannels.insert(std::make_pair(message->stream, channel));
 	}
@@ -133,7 +132,7 @@ void PeerConnection::forwardMessage(message_ptr message) {
 
 void PeerConnection::openDataChannels(void) {
 	for (auto it = mDataChannels.begin(); it != mDataChannels.end(); ++it) {
-		it->second->open();
+		it->second->open(mSctpTransport);
 	}
 }