Compare commits
	
		
			6 Commits
		
	
	
		
			v2.2.0
			...
			user/bserg
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4373a92c61 | ||
|  | 91e67f6e53 | ||
|  | 1ca1f612be | ||
|  | 1b9e55d3f8 | ||
|  | 0d80971328 | ||
|  | 80c1ed0611 | 
| @@ -5,5 +5,7 @@ compiler: | |||||||
|   - clang |   - clang | ||||||
| #   - gcc | #   - gcc | ||||||
|  |  | ||||||
|     # os: osx | os: osx | ||||||
| script: make test | # os: windows | ||||||
|  | # script: make test | ||||||
|  | script: python test/run.py | ||||||
|   | |||||||
| @@ -156,7 +156,9 @@ namespace ix | |||||||
|         _onCloseCallback = onCloseCallback;  |         _onCloseCallback = onCloseCallback;  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool WebSocketTransport::exceedSendHeartBeatTimeOut() |     // Only consider send time points for that computation. | ||||||
|  |     // The receive time points is taken into account in Socket::poll (second parameter). | ||||||
|  |     bool WebSocketTransport::heartBeatPeriodExceeded() | ||||||
|     { |     { | ||||||
|         std::lock_guard<std::mutex> lock(_lastSendTimePointMutex); |         std::lock_guard<std::mutex> lock(_lastSendTimePointMutex); | ||||||
|         auto now = std::chrono::steady_clock::now(); |         auto now = std::chrono::steady_clock::now(); | ||||||
| @@ -172,7 +174,7 @@ namespace ix | |||||||
|                 // send for a duration exceeding our heart-beat period, send a |                 // send for a duration exceeding our heart-beat period, send a | ||||||
|                 // ping to the server. |                 // ping to the server. | ||||||
|                 if (pollResult == PollResultType_Timeout &&  |                 if (pollResult == PollResultType_Timeout &&  | ||||||
|                     exceedSendHeartBeatTimeOut()) |                     heartBeatPeriodExceeded()) | ||||||
|                 { |                 { | ||||||
|                     std::stringstream ss; |                     std::stringstream ss; | ||||||
|                     ss << kHeartBeatPingMessage << "::" << _heartBeatPeriod << "s"; |                     ss << kHeartBeatPingMessage << "::" << _heartBeatPeriod << "s"; | ||||||
|   | |||||||
| @@ -126,7 +126,7 @@ namespace ix | |||||||
|         std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint; |         std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint; | ||||||
|  |  | ||||||
|         // No data was send through the socket for longer that the hearbeat period |         // No data was send through the socket for longer that the hearbeat period | ||||||
|         bool exceedSendHeartBeatTimeOut(); |         bool heartBeatPeriodExceeded(); | ||||||
|  |  | ||||||
|         void sendOnSocket(); |         void sendOnSocket(); | ||||||
|         WebSocketSendInfo sendData(wsheader_type::opcode_type type,  |         WebSocketSendInfo sendData(wsheader_type::opcode_type type,  | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| #include "IXTest.h" | #include "IXTest.h" | ||||||
| #include <ixwebsocket/IXWebSocket.h> | #include <ixwebsocket/IXWebSocket.h> | ||||||
|  | #include <ixwebsocket/IXNetSystem.h> | ||||||
|  |  | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <thread> | #include <thread> | ||||||
| @@ -14,12 +15,14 @@ | |||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <stack> | ||||||
|  |  | ||||||
| namespace ix | namespace ix | ||||||
| { | { | ||||||
|     std::atomic<size_t> incomingBytes(0); |     std::atomic<size_t> incomingBytes(0); | ||||||
|     std::atomic<size_t> outgoingBytes(0); |     std::atomic<size_t> outgoingBytes(0); | ||||||
|     std::mutex Logger::_mutex; |     std::mutex Logger::_mutex; | ||||||
|  |     std::stack<int> freePorts; | ||||||
|  |  | ||||||
|     void setupWebSocketTrafficTrackerCallback() |     void setupWebSocketTrafficTrackerCallback() | ||||||
|     { |     { | ||||||
| @@ -66,4 +69,52 @@ namespace ix | |||||||
|         Logger() << msg; |         Logger() << msg; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     int getFreePort() | ||||||
|  |     { | ||||||
|  |         int defaultPort = 8090; | ||||||
|  |  | ||||||
|  |         int sockfd;  | ||||||
|  |         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | ||||||
|  |         { | ||||||
|  |             log("Cannot compute a free port. socket error."); | ||||||
|  |             return defaultPort; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         int enable = 1; | ||||||
|  |         if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, | ||||||
|  |                        (char*) &enable, sizeof(enable)) < 0) | ||||||
|  |         { | ||||||
|  |             log("Cannot compute a free port. setsockopt error."); | ||||||
|  |             return defaultPort; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Bind to port 0. This is the standard way to get a free port. | ||||||
|  |         struct sockaddr_in server; // server address information | ||||||
|  |         server.sin_family = AF_INET; | ||||||
|  |         server.sin_port   = htons(0); | ||||||
|  |         server.sin_addr.s_addr = inet_addr("127.0.0.1"); | ||||||
|  |  | ||||||
|  |         if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) | ||||||
|  |         { | ||||||
|  |             log("Cannot compute a free port. bind error."); | ||||||
|  |  | ||||||
|  |             ::close(sockfd); | ||||||
|  |             return defaultPort; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         struct sockaddr_in sa; // server address information | ||||||
|  |         unsigned int len; | ||||||
|  |         if (getsockname(sockfd, (struct sockaddr *) &sa, &len) < 0) | ||||||
|  |         { | ||||||
|  |             log("Cannot compute a free port. getsockname error."); | ||||||
|  |  | ||||||
|  |             ::close(sockfd); | ||||||
|  |             return defaultPort; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         int port = ntohs(sa.sin_port); | ||||||
|  |         ::close(sockfd); | ||||||
|  |  | ||||||
|  |         return port; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,4 +51,7 @@ namespace ix | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     void log(const std::string& msg); |     void log(const std::string& msg); | ||||||
|  |  | ||||||
|  |     bool computeFreePorts(int count); | ||||||
|  |     int getFreePort(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -180,7 +180,7 @@ TEST_CASE("Websocket_heartbeat", "[heartbeat]") | |||||||
|     { |     { | ||||||
|         ix::setupWebSocketTrafficTrackerCallback(); |         ix::setupWebSocketTrafficTrackerCallback(); | ||||||
|  |  | ||||||
|         int port = 8093; |         int port = getFreePort(); | ||||||
|         ix::WebSocketServer server(port); |         ix::WebSocketServer server(port); | ||||||
|         std::atomic<int> serverReceivedPingMessages(0); |         std::atomic<int> serverReceivedPingMessages(0); | ||||||
|         REQUIRE(startServer(server, serverReceivedPingMessages)); |         REQUIRE(startServer(server, serverReceivedPingMessages)); | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ TEST_CASE("Websocket_server", "[websocket_server]") | |||||||
| { | { | ||||||
|     SECTION("Connect to the server, do not send anything. Should timeout and return 400") |     SECTION("Connect to the server, do not send anything. Should timeout and return 400") | ||||||
|     { |     { | ||||||
|         int port = 8091; |         int port = getFreePort(); | ||||||
|         ix::WebSocketServer server(port); |         ix::WebSocketServer server(port); | ||||||
|         REQUIRE(startServer(server)); |         REQUIRE(startServer(server)); | ||||||
|  |  | ||||||
| @@ -107,7 +107,7 @@ TEST_CASE("Websocket_server", "[websocket_server]") | |||||||
|  |  | ||||||
|     SECTION("Connect to the server. Send GET request without header. Should return 400") |     SECTION("Connect to the server. Send GET request without header. Should return 400") | ||||||
|     { |     { | ||||||
|         int port = 8092; |         int port = getFreePort(); | ||||||
|         ix::WebSocketServer server(port); |         ix::WebSocketServer server(port); | ||||||
|         REQUIRE(startServer(server)); |         REQUIRE(startServer(server)); | ||||||
|  |  | ||||||
| @@ -142,7 +142,7 @@ TEST_CASE("Websocket_server", "[websocket_server]") | |||||||
|  |  | ||||||
|     SECTION("Connect to the server. Send GET request with correct header") |     SECTION("Connect to the server. Send GET request with correct header") | ||||||
|     { |     { | ||||||
|         int port = 8093; |         int port = getFreePort(); | ||||||
|         ix::WebSocketServer server(port); |         ix::WebSocketServer server(port); | ||||||
|         REQUIRE(startServer(server)); |         REQUIRE(startServer(server)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,11 @@ | |||||||
|  *  Copyright (c) 2017 Machine Zone. All rights reserved. |  *  Copyright (c) 2017 Machine Zone. All rights reserved. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // Simple chat program that talks to the node.js server at | ||||||
|  | // websocket_chat_server/broacast-server.js | ||||||
|  | // | ||||||
|  |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <queue> | #include <queue> | ||||||
| @@ -24,7 +29,8 @@ namespace | |||||||
|     { |     { | ||||||
|         public: |         public: | ||||||
|             WebSocketChat(const std::string& user, |             WebSocketChat(const std::string& user, | ||||||
|                        const std::string& session); |                           const std::string& session, | ||||||
|  |                           int port); | ||||||
|  |  | ||||||
|             void subscribe(const std::string& channel); |             void subscribe(const std::string& channel); | ||||||
|             void start(); |             void start(); | ||||||
| @@ -40,6 +46,7 @@ namespace | |||||||
|         private: |         private: | ||||||
|             std::string _user; |             std::string _user; | ||||||
|             std::string _session; |             std::string _session; | ||||||
|  |             int _port; | ||||||
|  |  | ||||||
|             ix::WebSocket _webSocket; |             ix::WebSocket _webSocket; | ||||||
|  |  | ||||||
| @@ -47,9 +54,11 @@ namespace | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     WebSocketChat::WebSocketChat(const std::string& user, |     WebSocketChat::WebSocketChat(const std::string& user, | ||||||
|                                  const std::string& session) : |                                  const std::string& session, | ||||||
|  |                                  int port) : | ||||||
|         _user(user), |         _user(user), | ||||||
|         _session(session) |         _session(session), | ||||||
|  |         _port(port) | ||||||
|     { |     { | ||||||
|         ; |         ; | ||||||
|     } |     } | ||||||
| @@ -71,7 +80,16 @@ namespace | |||||||
|  |  | ||||||
|     void WebSocketChat::start() |     void WebSocketChat::start() | ||||||
|     { |     { | ||||||
|         std::string url("ws://localhost:8090/"); |         std::string url; | ||||||
|  |         { | ||||||
|  |             std::stringstream ss; | ||||||
|  |             ss << "ws://localhost:" | ||||||
|  |                << _port  | ||||||
|  |                << "/"; | ||||||
|  |  | ||||||
|  |             url = ss.str(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         _webSocket.setUrl(url); |         _webSocket.setUrl(url); | ||||||
|  |  | ||||||
|         std::stringstream ss; |         std::stringstream ss; | ||||||
| @@ -226,8 +244,8 @@ TEST_CASE("Websocket_chat", "[websocket_chat]") | |||||||
|         REQUIRE(startServer(server)); |         REQUIRE(startServer(server)); | ||||||
|  |  | ||||||
|         std::string session = ix::generateSessionId(); |         std::string session = ix::generateSessionId(); | ||||||
|         WebSocketChat chatA("jean", session); |         WebSocketChat chatA("jean", session, port); | ||||||
|         WebSocketChat chatB("paul", session); |         WebSocketChat chatB("paul", session, port); | ||||||
|  |  | ||||||
|         chatA.start(); |         chatA.start(); | ||||||
|         chatB.start(); |         chatB.start(); | ||||||
|   | |||||||
| @@ -34,6 +34,10 @@ if osName == 'Linux': | |||||||
|  |  | ||||||
| sanitizerFlags = sanitizersFlags[sanitizer] | sanitizerFlags = sanitizersFlags[sanitizer] | ||||||
|  |  | ||||||
|  | # if osName == 'Windows': | ||||||
|  | #     os.environ['CC'] = 'clang-cl' | ||||||
|  | #     os.environ['CXX'] = 'clang-cl' | ||||||
|  |  | ||||||
| cmakeCmd = 'cmake -DCMAKE_BUILD_TYPE=Debug {} {} ..'.format(generator, sanitizerFlags) | cmakeCmd = 'cmake -DCMAKE_BUILD_TYPE=Debug {} {} ..'.format(generator, sanitizerFlags) | ||||||
| print(cmakeCmd) | print(cmakeCmd) | ||||||
| ret = os.system(cmakeCmd) | ret = os.system(cmakeCmd) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user