Compare commits

..

1 Commits

Author SHA1 Message Date
499262f752 check max frame size 2019-10-26 11:48:03 -07:00
16 changed files with 25 additions and 266 deletions

View File

@ -107,7 +107,7 @@ elseif (WIN32)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/windows/IXSetThreadName_windows.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/freebsd/IXSetThreadName_freebsd.cpp)
else()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/linux/IXSetThreadName_linux.cpp)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSelectInterruptEventFd.cpp)
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSelectInterruptEventFd.h)

View File

@ -1 +1 @@
7.3.1
7.2.1

View File

@ -4,35 +4,7 @@
IXWebSocket is a C++ library for WebSocket client and server development. It has minimal dependencies (no boost), is very simple to use and support everything you'll likely need for websocket dev (SSL, deflate compression, compiles on most platforms, etc...). HTTP client and server code is also available, but it hasn't received as much testing.
It is been used on big mobile video game titles sending and receiving tons of messages since 2017 (iOS and Android). It was tested on macOS, iOS, Linux, Android, Windows and FreeBSD. Two important design goals are simplicity and correctness.
```
# Required on Windows
ix::initNetSystem();
# Our websocket object
ix::WebSocket webSocket;
std::string url("ws://localhost:8080/");
webSocket.setUrl(url);
// Setup a callback to be fired (in a background thread, watch out for race conditions !)
// when a message or an event (open, close, error) is received
webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr& msg)
{
if (msg->type == ix::WebSocketMessageType::Message)
{
std::cout << msg->str << std::endl;
}
}
);
// Now that our callback is setup, we can start our background thread and receive messages
webSocket.start();
// Send a message to the server (default to TEXT mode)
webSocket.send("hello world");
```
It is been used on big mobile video game titles sending and receiving tons of messages since 2017 (iOS and Android).
Interested ? Go read the [docs](https://machinezone.github.io/IXWebSocket/) ! If things don't work as expected, please create an issue in github, or even better a pull request if you know how to fix your problem.

View File

@ -1,14 +1,6 @@
# Changelog
All notable changes to this project will be documented in this file.
## [7.3.0] - 2019-11-15
- New ws command: `ws proxy_server`.
## [7.2.2] - 2019-11-01
- Tag a release + minor reformating.
## [7.2.1] - 2019-10-26
- Add unittest to IXSentryClient to lua backtrace parsing code

View File

@ -9,7 +9,6 @@
* Linux
* Android
* Windows
* FreeBSD
## Example code
@ -45,7 +44,3 @@ webSocket.send("hello world");
There are 2 main reasons that explain why IXWebSocket got written. First, we needed a C++ cross-platform client library, which should have few dependencies. What looked like the most solid one, [websocketpp](https://github.com/zaphoyd/websocketpp) did depend on boost and this was not an option for us. Secondly, there were other available libraries with fewer dependencies (C ones), but they required calling an explicit poll routine periodically to know if a client had received data from a server, which was not elegant.
We started by solving those 2 problems, then we added server websocket code, then an HTTP client, and finally a very simple HTTP server.
## Contributing
IXWebSocket is developed on [github](https://github.com/machinezone/IXWebSocket). We'd love to hear about how you use it ; opening up an issue in github is ok for that. If things don't work as expected, please create an issue in github, or even better a pull request if you know how to fix your problem.

View File

@ -195,15 +195,6 @@ Server: Python/3.7 websockets/8.0.2
Upgrade: websocket
```
## Websocket proxy
```
ws proxy_server --remote_host ws://127.0.0.1:9000 -v
Listening on 127.0.0.1:8008
```
If you connect to ws://127.0.0.1:8008, the proxy will connect to ws://127.0.0.1:9000 and pass all traffic to this server.
## File transfer
```

View File

@ -20,7 +20,6 @@ namespace snake
{
return _nonce;
}
void setNonce(const std::string& nonce)
{
_nonce = nonce;

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "7.3.1"
#define IX_WEBSOCKET_VERSION "7.1.0"

View File

@ -8,9 +8,10 @@
#include "catch.hpp"
#include <iostream>
#include <ixsentry/IXSentryClient.h>
#include <string.h>
#include <ixsentry/IXSentryClient.h>
using namespace ix;
namespace ix
@ -20,9 +21,7 @@ namespace ix
SECTION("Attempt to index nil")
{
SentryClient sentryClient("");
std::string stack = "Attempt to index nil[overlay]!\nstack traceback:\n\tfoo.lua:2661: "
"in function 'getFoo'\n\tfoo.lua:1666: in function "
"'onUpdate'\n\tfoo.lua:1751: in function <foo.lua:1728>";
std::string stack = "Attempt to index nil[overlay]!\nstack traceback:\n\tfoo.lua:2661: in function 'getFoo'\n\tfoo.lua:1666: in function 'onUpdate'\n\tfoo.lua:1751: in function <foo.lua:1728>";
auto frames = sentryClient.parseLuaStackTrace(stack);
REQUIRE(frames.size() == 3);
@ -31,8 +30,7 @@ namespace ix
SECTION("Attempt to perform nil")
{
SentryClient sentryClient("");
std::string stack = "Attempt to perform nil - 1572111278.299\nstack "
"traceback:\n\tfoo.lua:57: in function <foo.lua:53>";
std::string stack = "Attempt to perform nil - 1572111278.299\nstack traceback:\n\tfoo.lua:57: in function <foo.lua:53>";
auto frames = sentryClient.parseLuaStackTrace(stack);
REQUIRE(frames.size() == 1);

View File

@ -55,7 +55,6 @@ add_executable(ws
ws_cobra_metrics_to_redis.cpp
ws_httpd.cpp
ws_autobahn.cpp
ws_proxy_server.cpp
ws.cpp)
target_link_libraries(ws ixsnake)

View File

@ -72,7 +72,6 @@ int main(int argc, char** argv)
std::string redisPassword;
std::string appsConfigPath("appsConfig.json");
std::string subprotocol;
std::string remoteHost;
ix::SocketTLSOptions tlsOptions;
std::string ciphers;
std::string redirectUrl;
@ -305,12 +304,6 @@ int main(int argc, char** argv)
redisServerApp->add_option("--port", port, "Port");
redisServerApp->add_option("--host", hostname, "Hostname");
CLI::App* proxyServerApp = app.add_subcommand("proxy_server", "Proxy server");
proxyServerApp->add_option("--port", port, "Port");
proxyServerApp->add_option("--host", hostname, "Hostname");
proxyServerApp->add_option("--remote_host", remoteHost, "Remote Hostname");
proxyServerApp->add_flag("-v", verbose, "Verbose");
CLI11_PARSE(app, argc, argv);
// pid file handling
@ -449,10 +442,6 @@ int main(int argc, char** argv)
{
ret = ix::ws_redis_server_main(port, hostname);
}
else if (app.got_subcommand("proxy_server"))
{
ret = ix::ws_proxy_server_main(port, hostname, tlsOptions, remoteHost, verbose);
}
else if (version)
{
std::cout << "ws " << ix::userAgent() << std::endl;

View File

@ -142,10 +142,4 @@ namespace ix
int ws_autobahn_main(const std::string& url, bool quiet);
int ws_redis_server_main(int port, const std::string& hostname);
int ws_proxy_server_main(int port,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions,
const std::string& remoteHost,
bool verbose);
} // namespace ix

View File

@ -128,21 +128,23 @@ namespace ix
{
spdlog::info("Subscriber authenticated");
conn.subscribe(
channel,
filter,
[&msgPerSeconds, &msgCount, &conditionVariableMutex, &condition, &queue](
const Json::Value& msg) {
{
std::unique_lock<std::mutex> lock(conditionVariableMutex);
queue.push(msg);
}
conn.subscribe(channel,
filter,
[&msgPerSeconds,
&msgCount,
&conditionVariableMutex,
&condition,
&queue](const Json::Value& msg) {
{
std::unique_lock<std::mutex> lock(conditionVariableMutex);
queue.push(msg);
}
condition.notify_one();
condition.notify_one();
msgPerSeconds++;
msgCount++;
});
msgPerSeconds++;
msgCount++;
});
}
else if (eventType == ix::CobraConnection_EventType_Subscribed)
{

View File

@ -4,12 +4,12 @@
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
*/
#include <ixsentry/IXSentryClient.h>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <ixsentry/IXSentryClient.h>
#include <mutex>
#include <queue>
#include <spdlog/spdlog.h>

View File

@ -1,5 +1,5 @@
/*
* ws_echo_server.cpp
* ws_broadcast_server.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/

View File

@ -1,172 +0,0 @@
/*
* ws_proxy_server.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixwebsocket/IXWebSocketServer.h>
#include <sstream>
namespace ix
{
class ProxyConnectionState : public ix::ConnectionState
{
public:
ProxyConnectionState()
: _connected(false)
{
}
ix::WebSocket& webSocket()
{
return _serverWebSocket;
}
bool isConnected()
{
return _connected;
}
void setConnected()
{
_connected = true;
}
private:
ix::WebSocket _serverWebSocket;
bool _connected;
};
int ws_proxy_server_main(int port,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions,
const std::string& remoteUrl,
bool verbose)
{
std::cout << "Listening on " << hostname << ":" << port << std::endl;
ix::WebSocketServer server(port, hostname);
server.setTLSOptions(tlsOptions);
auto factory = []() -> std::shared_ptr<ix::ConnectionState> {
return std::make_shared<ProxyConnectionState>();
};
server.setConnectionStateFactory(factory);
server.setOnConnectionCallback([remoteUrl,
verbose](std::shared_ptr<ix::WebSocket> webSocket,
std::shared_ptr<ConnectionState> connectionState) {
auto state = std::dynamic_pointer_cast<ProxyConnectionState>(connectionState);
// Server connection
state->webSocket().setOnMessageCallback([webSocket, state, verbose](
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
std::cerr << "New connection" << std::endl;
std::cerr << "id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
std::cerr << it.first << ": " << it.second << std::endl;
}
state->setConnected();
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
std::stringstream ss;
ss << "Connection error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cerr << ss.str();
webSocket->close(msg->closeInfo.code, msg->closeInfo.reason);
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
std::cerr << "Received " << msg->wireSize << " bytes from server" << std::endl;
if (verbose)
{
std::cerr << "payload " << msg->str << std::endl;
}
webSocket->send(msg->str, msg->binary);
}
});
// Client connection
webSocket->setOnMessageCallback([state, remoteUrl, verbose](
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
std::cerr << "New connection" << std::endl;
std::cerr << "id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
std::cerr << it.first << ": " << it.second << std::endl;
}
// Connect to the 'real' server
std::string url(remoteUrl);
url += msg->openInfo.uri;
state->webSocket().setUrl(url);
state->webSocket().start();
// we should sleep here for a bit until we've established the
// connection with the remote server
while (!state->isConnected())
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
state->webSocket().close(msg->closeInfo.code, msg->closeInfo.reason);
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
std::stringstream ss;
ss << "Connection error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
std::cerr << "Received " << msg->wireSize << " bytes from client" << std::endl;
if (verbose)
{
std::cerr << "payload " << msg->str << std::endl;
}
state->webSocket().send(msg->str, msg->binary);
}
});
});
auto res = server.listen();
if (!res.first)
{
std::cerr << res.second << std::endl;
return 1;
}
server.start();
server.wait();
return 0;
}
} // namespace ix