Browse Source

Fixed WebSocket sending multiple close frames

Paul-Louis Ageneau 2 years ago
parent
commit
8cb527688b
2 changed files with 9 additions and 3 deletions
  1. 5 2
      src/impl/wstransport.cpp
  2. 4 1
      src/impl/wstransport.hpp

+ 5 - 2
src/impl/wstransport.cpp

@@ -94,6 +94,9 @@ void WsTransport::close() {
 	if (state() != State::Connected)
 		return;
 
+	if (mCloseSent.exchange(true))
+		return;
+
 	PLOG_INFO << "WebSocket closing";
 	try {
 		sendFrame({CLOSE, NULL, 0, true, mIsClient});
@@ -329,14 +332,14 @@ void WsTransport::recvFrame(const Frame &frame) {
 		break;
 	}
 	case CLOSE: {
-		close();
 		PLOG_INFO << "WebSocket closed";
+		close();
 		changeState(State::Disconnected);
 		break;
 	}
 	default: {
+		PLOG_WARNING << "Unknown WebSocket opcode: " + to_string(frame.opcode);
 		close();
-		throw std::invalid_argument("Unknown WebSocket opcode: " + to_string(frame.opcode));
 	}
 	}
 }

+ 4 - 1
src/impl/wstransport.hpp

@@ -25,6 +25,8 @@
 
 #if RTC_ENABLE_WEBSOCKET
 
+#include <atomic>
+
 namespace rtc::impl {
 
 class TcpTransport;
@@ -80,8 +82,9 @@ private:
 	binary mBuffer;
 	binary mPartial;
 	Opcode mPartialOpcode;
-	int mOutstandingPings = 0;
 	std::mutex mSendMutex;
+	int mOutstandingPings = 0;
+	std::atomic<bool> mCloseSent = false;
 };
 
 } // namespace rtc::impl