Coder Social home page Coder Social logo

eidheim / simple-websocket-server Goto Github PK

View Code? Open in Web Editor NEW
799.0 81.0 279.0 372 KB

A very simple, fast, multithreaded, platform independent WebSocket (WS) and WebSocket Secure (WSS) server and client library implemented using C++11, Boost.Asio and OpenSSL. Created to be an easy way to make WebSocket endpoints in C++.

License: MIT License

C++ 96.85% CMake 2.82% HTML 0.33%
cpp websocket websocket-secure ws wss server client asio library

simple-websocket-server's Introduction

This project has moved to https://gitlab.com/eidheim/Simple-WebSocket-Server.

Simple-WebSocket-Server

A very simple, fast, multithreaded, platform independent WebSocket (WS) and WebSocket Secure (WSS) server and client library implemented using C++11, Asio (both Boost.Asio and standalone Asio can be used) and OpenSSL. Created to be an easy way to make WebSocket endpoints in C++.

See https://gitlab.com/eidheim/Simple-Web-Server for an easy way to make REST resources available from C++ applications. Also, feel free to check out the new C++ IDE supporting C++11/14/17: https://gitlab.com/cppit/jucipp.

Features

  • RFC 6455 mostly supported: text/binary frames, fragmented messages, ping-pong, connection close with status and reason.
  • Asynchronous message handling
  • Thread pool if needed
  • Platform independent
  • WebSocket Secure support
  • Timeouts, if any of SocketServer::timeout_request and SocketServer::timeout_idle are >0 (default: SocketServer::timeout_request=5 seconds, and SocketServer::timeout_idle=0 seconds; no timeout on idle connections)
  • Simple way to add WebSocket endpoints using regex for path, and anonymous functions
  • An easy to use WebSocket and WebSocket Secure client library
  • C++ bindings to the following OpenSSL methods: Base64, MD5, SHA1, SHA256 and SHA512 (found in crypto.hpp)

Usage

See ws_examples.cpp or wss_examples.cpp for example usage.

Dependencies

  • Boost.Asio or standalone Asio
  • OpenSSL libraries

Compile

Compile with a C++11 supported compiler:

mkdir build
cd build
cmake ..
make
cd ..

Run server and client examples

WS

./build/ws_examples

WSS

Before running the WSS-examples, an RSA private key (server.key) and an SSL certificate (server.crt) must be created. Follow, for instance, the instructions given here (for a self-signed certificate): http://www.akadia.com/services/ssh_test_certificate.html

Then:

./build/wss_examples

simple-websocket-server's People

Contributors

ar90n avatar assoftware avatar bazzz01010101 avatar bryant1410 avatar classix-do avatar davepuchyr avatar dlinten avatar eidheim avatar joshblum avatar matrixman87 avatar xhellerx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-websocket-server's Issues

ssl connection failed

Just follow the steps, but once I did ssl connection, it crashed, which stack is as bellow. anything wrong with my settings. Tried different browser no help.

python SimpleExampleServer.py --example chat --ssl 1 --cert ./cert.pem
Traceback (most recent call last):
File "SimpleExampleServer.py", line 71, in
server.serveforever()
File "/root/kw/wss/SimpleWebSocketServer.py", line 696, in serveforever
super(SimpleSSLWebSocketServer, self).serveforever()
File "/root/kw/wss/SimpleWebSocketServer.py", line 654, in serveforever
client.handleClose()
File "SimpleExampleServer.py", line 38, in handleClose
clients.remove(self)
ValueError: list.remove(x): x not in list

Support g++ below 4.9

Can you support older compiler versions? It seems only thing you need is to replace std::regex with boost::regex or add some kind of macro to choose between them.

Getter to Class Connection Status

Hi,
First of all, thank you for this great library !

I was wondering, how do I get the status of a Connection ?
Let me explain, in my program, each of the Server's Clients are linked with a User, therefore when a Client connects to the WsServer, I instantiate a new User and store the Connection in it.

But when i need to clean my list of User, I would like to know the status of the socket so that I can delete the User when the connection is lost.
With that idea in mind, in my class User you can see that I had to create a boolean closed, this variable is set to true by the WsServer.on_close function.

The User class looks like that:

class User{
        std::shared_ptr<WsServer::Connection> connection;
        Player* player;
        bool closed;
        //...
    public:
        User(std::shared_ptr<WsServer::Connection> co, Player* pl): 
                 connection(co), player(pl), closed(false){}
        ~User(){
          delete player;
        }
        bool closed(){
           return closed;
        }
    };

Do you think it is possible to add a getter to the Connection Class to get it's status ?

Binary data in Message?

Is it possible to get the binary data from WsServer::Message? The idea is that we don't necessary always send strings, in my project, I am actually sending binaries.

Thanks.

asynchronous onmessage ?

Hi there,

looking at client_ws.hpp, it is not clear to me whether the "ping" between client and server will go on in the background, while onmessage() does its work (see "read_message_content" -- it appears as if either the ping or the onmessage function run, but not both).

My use-case may involve quite long times without any user-defined interaction between client and server (from minutes to days), while the data obtained from the server is processed within the onmessage function. This is for an application involving distributed parametric optimisation, so data transfers are generally small -- a few kilobytes -- but evaluation times may be quite long.

So, do I need to send my calculation into the background in its own thread and if so, do I need to take care of the synchronization of the final client.send() command issued by this thread ? After all the ping will continue in any case, if I do "expensive" calculations in a thread.

I would also like to understand what action is taken by client and server if the ping does not get an answer for a predefined number of submissions or time. Will this result in an onerror() call?

In any case, thanks for a great library!

Kind Regards,
Beet

Server receives only one sent message

In my test project I have a WSS-websocket server and a WSS-client. I make several connections to several endpoints to the server. For each client connection I start a new thread managing this connection. When I try to send some messages in a loop to the server, the server only reveives one message. When I call a send_close() in the onmessage-functor in the client, the server receives all messages sent by the client. Is there a way to receive all messages without calling send_close() each time when a message was sent back?

internal_io_service not reset in stop() ?

Hi there,
it appears as if the internal_io_service variable, while being set by SimpleWeb::start(), is not being reset to false by SimpleWeb::stop() ? Essentially I would expect stop() to return SimpleWeb into a pristine condition.
Kind Regards,
Beet

How to test the simple-websocket-server with the client

We are trying to run the websocket server and the port is getting listened,but we couldn't accept the websocket client connection. We suspect that the callback handler is not working.Can you please assist us on this.

Thanks in advance,
Ragu R

MSVC warnings

As far as I can tell, everything works, so I'm not sure if you care about this--but just in case you do...

Since my project builds with "treat warnings as errors" I had to explicitly ignore the following msvc warnings in order to use your libraries:

Simple-WebSocket-Server

#pragma warning(disable:4251)
#pragma warning(disable:4458)
#pragma warning(disable:4244)
#include "Simple-WebSocket-Server\server_ws.hpp

Simple-WebSocket-Server (client)

#pragma warning(disable:4244)
#include "Simple-WebSocket-Server\client_ws.hpp

Simple-WebServer

#pragma warning(disable:4503)
#pragma warning(disable:4101)
#pragma warning(disable:4458)
#pragma warning(disable:4457)
#pragma warning(disable:4244)
#pragma warning(disable:4251)
#include "Simple-Web-Server/server_http.hpp

Simple-WebServer (client)

#pragma warning(disable:4456)
#pragma warning(disable:4100)
#pragma warning(disable:4244)
#include "Simple-Web-Server/client_http.hpp

I tried my hand at fixing them and didn't succeed--but my C++ kung fu is not strong. If you do want to address these, I'd be happily take another crack at fixing the ones I can and then get you some more information about the ones that I can't. Just thought you might like to know.

errors only in Release mode

Hi,
we are developing a Secure WebSocket Server making use of this brillant project. It works fine receiving and sending messages to various clients, but, when the time-delay of received messages goes down to less than 300 ms (or more) it starts behaving strangely, giving out errores and closing the connection. The strangest thing is that it fails only when in release configuration (in Debug Mode no error whatsoever). It seems to be non related to the part of the server we wrote. The error codes are the following:
10053
10054
336151548.

Can this package be added to vcpkg?

vcpkg is now the preferred way to install open source packages in Microsoft Visual C++.
Boost and Beast libraries are in there.
Can this package also be added to vcpkg? (GitHub.com/Microsoft/vcpkg)

Allow to set the order of endpoints

The endpoint member of a server is actually a std::map, which gets sorted automatically each time after an element was inserted. When starting the server, the endpoint map is copied into a vector without ordering. So the order of the map is kept.

If you have two endpoints "^/abc/?$" and "^/([a-z]+)/?$" in the map, then the more greedy endpoint will be used first because of the order of the map elements. Because the endpoint "abc" is contained in the regexp "[a-z]+", the endpoint functions (onOpen, onMessage, etc.) of "abc" will be never set.

Sorting the regexp-vector after copying the endpoints-map with respect to an endpoint-order set by the user should fix the problem. For instance I have added a member

        int order = 0;

into the public section of the endpoint class. After starting the server and copying the map a sort-function will be applied on the vector:

        std::sort(opt_endpoint.begin(), opt_endpoint.end(), [](const std::pair<boost::regex, Endpoint*>& a,
                                                               const std::pair<boost::regex, Endpoint*>& b)
        {
            return a.second->order < b.second->order;
        });

Do you see any problems adding this feature to the code?

WSS seems not to work.

Hey,
i got an issue setting up the secure websocket server.
The non secured works without any problems.

I have an official wildcard certificate for my domain ghsys.net
The server is running with the private key, as server.key and the certificate as server.crt. It is also starting up, but my JS client displays the following error at the console:
WebSocket connection to 'wss://bots01.prod.ghsys.net:8080/echo' failed: WebSocket opening handshake was canceled

I also tried putting the CA to the server.crt which did not resolve the problem.
Is there anything i have missed?

Passing connection errors to the onerror() handler?

Hi,

I have question/change request regarding the error handling in the websocket client.
When I use websocket in JavaScript, and the target host is not available, or not accepting connections, then first the onerror-Handler gets called with the connection error and then the onclose-Handler gets called.

Currently it's implemented that if the server doesn't respond and the async_connect() fails, the exception thrown here will go up the callstack until it terminates the io_service.run() call, and has to be handled by the thread running the io_service. This makes it difficult to map the error onto a specific websocket connection and retry to open the connection later.

I would suggest to call onerror(ec) & onclose() (or only onerror(ec)) instead of throwing an exception.
Maybe it's better to generally call onerror(ec) instead of throwing the exception.

Connection closed before receiving a handshake response

I simply did

git clone https://github.com/eidheim/Simple-WebSocket-Server.git

Then compiled in linux

g++ -O3 -std=c++1y ws_examples.cpp -lboost_system -lcrypto -lpthread -o ws_examples

Wrote a sample JS client as specified in documentation

<!Doctype html>
<html>
    <head>
        <title>
            Web Socket 
        </title>
   </head>
<body>
    <script>

var ws=new WebSocket("ws://localhost:8080/echo");
ws.onmessage=function(evt){console.log(evt.data);};
ws.send("test");


    </script>
</body>
</html>

But when I run client and server, It gives error

Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
WebSocket connection to 'ws://localhost:8080/echo' failed: Connection closed before receiving a handshake response

Can you please direct where is things going wrong ?

Ubuntu 14
Boost 0.9.8
No trace was received on server side

Compilation Issue with Windows Visual Studio 2012

Hi there,

On Windows machine, we added the header files to our Visual Studio c++ project. Yet, we cannot get it compiled since it does not have support for c++11. Do you have any solution for it?

Regards,

Incomplete commands in readme - missing "-lpthread"

Hi, I just downloaded your code.
Trying to compile ( as in readme ) and got this ( linker ) error:

/usr/bin/ld: /tmp/ccYLDbF9.o: undefined reference to symbol 'pthread_create@@GLIBC_2.1'
/usr/lib/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Please update your readme by adding: "-lpthread" to your commands.

For example - change line:
g++ -O3 -std=c++1y ws_examples.cpp -lboost_system -lcrypto -o ws_examples
to
g++ -O3 -std=c++1y ws_examples.cpp -lboost_system -lcrypto -o ws_examples -lpthread

Thanks for your interesting project.
I'm going to use it in future.

Acting on a failed connect()

Hi again,

from what I understand, the client-side connect() call has the sole option to throw from within the onerror() call to let the audience know that something went wrong. Any chance of returning a boolean or giving access to the error code through a reference argument ?

All clients and the server will be started in a compute cluster in my case, usually through some submission script and via a batch queue. It is not guaranteed that the server is available immediately. Hence I'd like to loop on the connect() call for a number of times on the client side, so the server has time to start up.

This would be easiest if connect() would return a bool, something like

while(!connect() && nConnectionAttempts++ < maxConnectionAttempts);

Thanks and Best Regards,
Beet

how to make server_send() synchronous

So sorry I don't quite understand your instruction of issue #23. If you mean sleep_for() cause the delay problem, however, I marked the sleep_for() didn't solve the delay problem.

I read the comment in
https://github.com/eidheim/Simple-WebSocket-Server/blob/master/ws_examples.cpp#L79

I believe it mean server.send() command doesn't send immediately. Even more, if I used a
for loop to send binary as a series of chunk, just like shown in #23, seems very probably
arrived not as the same order as I send them out.

Is there any flag or any other way to send binary chunk immediately and synchronous in order?

crypto.h has link error

inline std::string encode(const std::string &ascii) {
all the function should be inline or will have link error if two cpp file include it

more than 5 seconds delay to send binary data

Based on ws_examples


auto send_stream=make_shared<WsClient::SendStream>();
{
    std::ifstream infile(JPG_FILE, ios::in | ios::binary);
    std::ofstream outfile ("new.jpg",std::ofstream::binary);

    // get size of file
    infile.seekg (0,infile.end);
    long nSize = infile.tellg();
    infile.seekg (0);

    char* buffer = new char[nSize];

    // read content of infile
    infile.read (buffer,nSize);

          for(int i=0; i<nSize; i+=SEND_SIZE)
          {
            auto send_stream=make_shared<WsClient::SendStream>();
            // write to outfile
            int send_size = i< (nSize-SEND_SIZE) ? SEND_SIZE:(nSize-i);
            cout << "Client: Sending binary: " << i << "," << send_size << endl;

            send_stream->write(&buffer[i], send_size);
            outfile.write (&buffer[i], send_size);
            client.send(send_stream, nullptr, 130);

            this_thread::sleep_for(chrono::milliseconds(200));
          }
    outfile.write (buffer, nSize);

    // release dynamically-allocated memory
    delete[] buffer;
    infile.close();
    outfile.close();
}
client.send(send_stream, nullptr, 130);

console output :


...
Client: Sending binary: 264000,8000
Client: Sending binary: 272000,8000
Client: Sending binary: 280000,8000
Client: Sending binary: 288000,8000
...


the same test case as issue #13
I sent a binary data using WsClient just like ws_example did.
I found even though the console shown data sent immediately, but websocket always got data after more than 5 seconds later. I used wireshock to confirm data from WsClient indeed arrived more than 5 seconds after client shown sent.

I also tried to use python websocket client to confirm delay is not because of network problem. Only
data sent by WsClient has long delay.

I am curious if I did anything wrong sort of caching the send buffer, but not really sent right after I called client.send()?

why not using std::move in SendData?

class SendData {
public:
SendData(std::shared_ptr header_stream, std::shared_ptr message_stream,
const std::function<void(const boost::system::error_code)> &callback) :
# header_stream(std::move(header_stream)), message_stream(std::move(message_stream)), callback(callback) {}
std::shared_ptr header_stream;
std::shared_ptr message_stream;
std::function<void(const boost::system::error_code)> callback;
};
I think using std::move has better performance? some post using lambda maybe using std::move bind some variable maybe more better?

Why message's data is a stream?

From my understanding of your code, each time a message is received, the data is copied to a fresh message object. So the data stored in the message won't change or increase: it could be a simple string instead of an istream. Then, the length field would be superfluous. In fact, the Message class could even inherit from std::string.

The benefits would be a much easier manipulation of the message and most of the time at least one less copy of it.

I could propose a patch if this make sense to you.

Removing dependency on Boost

Hi,
Excellent library, congrats.
Do you consider removing dependency on Boost? Quick skimming through your code showed very few dependency on Boost (like error_code, which can be taken from std).
Of course, the heart - Asio - but that does not need to be from Boost. There is a version of non-Boost (see on asio home page http://think-async.com/Asio/AsioAndBoostAsio).
Disclaimer - I do not have anything against Boost - but removing dependency might be better for those not wanting to compile/use it.

Question about data stream types

Hi,
i've successfully managed to send strings to javascript, but is it also possible, and perhaps more efficient to send integers and floats? I am now sending vectors of doubles as a string stream, but maybe there is a more efficient solution?

v1.2 not working anymore

Hi,

today I have updated my version to v1.2.1. Compilation was still successful, but it did not work anymore. There was no crash, but no endpoint can be created while the ws-server is running. I have a program adding new endpoints to the server when a specific message was sent. So I could send this message, and it seems to create an endpoitn like "^test/[a-zA-Z0-9]+/?$" waiting for new endpoint connections to create, but it didn't create any new endpoints since version 1.2 for example when the client wants to connect to "test/ep1". Also, I cannot see Boost::Log messages on the console anymore. Do you know why?

How to use for binary data?

Hi, your Readme says this supports "text/binary frames". How do you send and receive binary data? I don't see any examples in the tests..

thanks!

JavaScript test failed

After compiling:
g++ -O3 -std=c++1y ws_examples.cpp -lboost_system -lcrypto -o ws_examples -lpthread
just run:
./ws_examples
I create a blank HTML5 page with your code:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebSocket Test</title>
</head>
<body>
<script>
window.onload=function(){
var ws=new WebSocket("ws://localhost:8080/echo");
ws.onmessage=function(evt){console.log(evt.data);};
ws.send("test");
}
</script>
</body>
</html>

Just open this in Firefox 37.0.1 and got:

Connection with ws://localhost:8080/echo was interrupted while the page was loading
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

Server log:
Server: Opened connection 3062891680
Client: Opened connection
Client: Sending message: "Hello"
Server: Message received: "Hello" from 3062891680
Server: Sending message "Hello" to 3062891680
Client: Message received: "Hello"
Client: Sending close connection
Server: Closed connection 3062891680 with status code 1000
Client: Closed connection with status code 1000
Server: Opened connection 3062892680
Server: Closed connection 3062892680 with status code 1001

self signed certificate

Trying to connect from a javascript client to the server but I can't seem to get it to do it.
The certificate is self signed. First the client browser sends a GET to the other http server (your simple web server Eidheim) which uses the self signed certificate to get the rest file. That works fine as long as the first time an exception is created in the browser to accept the self signed certificate.
The html file that is distributed that way does a connect in that fashion to the secure websocket server (The code provided in this repo):
websocket = new WebSocket(wsUri); where wsUri is :
var wsUri = "wss://localhost:7777";
the port was changed from 8080 to 7777 so not to conflict with the simple web server
I read here and there I may have a problem with the self signing certificate that wss just won't trust and won't give any warning about, and just error the connection.
If I point browser (any) to wss://localhost:7777 or wss://127.0.0.1:7777 or wss://[machine name]:7777 I get nowhere, so I can't get the message to pop up for me to add an exception.
Not sure how to get some traction with my self signing certificate. Using a self signing certificate should work for me as it should be an option for people who install my product and may not have a verified certificate to provide

Problem With Sending Multiple Messages to Client

Related to #11.

Following the ws_example.cpp the code below shows that sending multiple responses to a client is not handled properly. I want to be able to send multiple responses to the client so it can process them separately. Am I using the library incorrectly or is this a concurrency issue? The example seems to be independent of the variable NUM_THREADS, I think the problem is how the send function on the server handles the streams.

#include "server_ws.hpp"
#include "client_ws.hpp"

#define NUM_THREADS 4

using namespace std;

typedef SimpleWeb::SocketServer<SimpleWeb::WS> WsServer;
typedef SimpleWeb::SocketClient<SimpleWeb::WS> WsClient;

void send_message(WsServer* server, shared_ptr<WsServer::Connection> connection, std::string msg)
{
  cout << "Server: Sending Message: "  << msg << endl;
  auto send_stream=make_shared<WsServer::SendStream>();
  *send_stream << msg;
  //server.send is an asynchronous function
  server->send(connection, send_stream, [server, connection](const boost::system::error_code& ec){
      if(ec) {
      cout << "Server: Error sending message. " <<
      //See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference.html, Error Codes for error code meanings
      "Error: " << ec << ", error message: " << ec.message() << endl;
      }
      });
}

int main() {
  //WebSocket (WS)-server at port 8080 using 4 threads
  WsServer server(8080, NUM_THREADS);

  auto& test=server.endpoint["^/test/?$"];

  test.onmessage=[&server](shared_ptr<WsServer::Connection> connection, shared_ptr<WsServer::Message> message) {
    auto message_str=message->string();
    cout << "Server: Message received: \"" << message_str << "\" from " << (size_t)connection.get() << endl;
    send_message(&server, connection, "test1");
    send_message(&server, connection, "test2");
  };

  test.onopen=[](shared_ptr<WsServer::Connection> connection) {
    cout << "Server: Opened connection " << (size_t)connection.get() << endl;
  };

  //See RFC 6455 7.4.1. for status codes
  test.onclose=[](shared_ptr<WsServer::Connection> connection, int status, const string& reason) {
    cout << "Server: Closed connection " << (size_t)connection.get() << " with status code " << status << endl;
  };

  //See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference.html, Error Codes for error code meanings
  test.onerror=[](shared_ptr<WsServer::Connection> connection, const boost::system::error_code& ec) {
    cout << "Server: Error in connection " << (size_t)connection.get() << ". " << 
      "Error: " << ec << ", error message: " << ec.message() << endl;
  };



  thread server_thread([&server](){
      //Start WS-server
      server.start();
      });

  //Wait for server to start so that the client can connect
  this_thread::sleep_for(chrono::seconds(1));

  WsClient client("localhost:8080/test");
  client.onmessage=[&client](shared_ptr<WsClient::Message> message) {
    auto message_str=message->string();

    cout << "Client: Message received:" << message_str << endl;
  };

  client.onopen=[&client]() {
    cout << "Client: Opened connection" << endl;

    string message="Hello";
    cout << "Client: Sending message: \"" << message << "\"" << endl;

    auto send_stream=make_shared<WsClient::SendStream>();
    *send_stream << message;
    client.send(send_stream);
  };

  client.onclose=[](int status, const string& reason) {
    cout << "Client: Closed connection with status code " << status << endl;
  };

  //See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference.html, Error Codes for error code meanings
  client.onerror=[](const boost::system::error_code& ec) {
    cout << "Client: Error: " << ec << ", error message: " << ec.message() << endl;
  };

  client.start();

  server_thread.join();

  return 0;
}

Client cannot be deleted properly

When I want to use SocketClient pointers I cannot delete the SocketClient objects properly due to a missing virtual destructor. The compiler shows a warning on that:

deleting object of polymorphic class type 'SimpleWeb::SocketClientboost::asio::basic_stream_socket<boost::asio::ip::tcp >' which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete client[i];
^

Can you fix it please :-)

more than 5 seconds delay to send binary data

Based on ws_examples

auto send_stream=make_sharedWsClient::SendStream();
{
std::ifstream infile(JPG_FILE, ios::in | ios::binary);
std::ofstream outfile ("new.jpg",std::ofstream::binary);

// get size of file
infile.seekg (0,infile.end);
long nSize = infile.tellg();
infile.seekg (0);

char* buffer = new char[nSize];

// read content of infile
infile.read (buffer,nSize);

      for(int i=0; i<nSize; i+=SEND_SIZE)
      {
        auto send_stream=make_shared<WsClient::SendStream>();
        // write to outfile
        int send_size = i< (nSize-SEND_SIZE) ? SEND_SIZE:(nSize-i);
        cout << "Client: Sending binary: " << i << "," << send_size << endl;

        send_stream->write(&buffer[i], send_size);
        outfile.write (&buffer[i], send_size);
        client.send(send_stream, nullptr, 130);

        this_thread::sleep_for(chrono::milliseconds(200));
      }
outfile.write (buffer, nSize);

// release dynamically-allocated memory
delete[] buffer;
infile.close();
outfile.close();

}

client.send(send_stream, nullptr, 130);

console output :

...
Client: Sending binary: 264000,8000
Client: Sending binary: 272000,8000
Client: Sending binary: 280000,8000
Client: Sending binary: 288000,8000

...

the same test case as issue #13
I sent a binary data using WsClient just like ws_example did.
I found even though the console shown data sent immediately, but websocket always got data after more than 5 seconds later. I used wireshock to confirm data from WsClient indeed arrived more than 5 seconds after client shown sent.

I also tried to use python websocket client to confirm delay is not because of network problem. Only
data sent by WsClient has long delay.

I am curious if I did anything wrong sort of caching the send buffer and not really sent right after I called client.send()?

Make openssl dependency optional?

I am attempting to use this library for an internal project. I would REALLY like to avoid openssl. Could you make openssl optional?

Sharing the same io_service

Big fan of the Simle-Web-Server, excited to try this library also. Is there a way to have it share the same io_service as another thread?

Message size limit (somewhere between 60kB and 70kB)

In order to rule out the possibility that this issue had anything to do with message content, I generated a file that was 75k of the letter h. I then sent a message containing that payload from the server to the client.

The server acted as if nothing was wrong, but nothing happened at the client, so I sent it again.

This time, the client received the message. Then I sent it again.

This time, the client closed the connection:

Closed Connection with code: 26728 Reason: hhhhhhü⌂ ☺%╘ ☺%╘hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

I find that I get this behavior with 70000 h's, but 60000 h's works just fine.

I'm building a cross-platform app and I noticed this behavior while using Visual Studio 2015 on Windows Server 2012. I haven't tested it out on gcc yet, but I will do so next time I'm in Linux mode.

Here's a gist containing the code I'm using.

Server init message

I am looking to send a server init message without the client first connecting to the server via web socket. An example might be an http or https request to whos response may include a web socket message from the server.

Something to the effect of:

//intent here is to pass in a connection made via different protocol to use for a response back
std::shared_ptr<WsServer::Connection> connection(new WsServer::Connection(new WS(http_session->socket().get_io_service())));

        auto send_stream = std::make_shared<WsServer::SendStream>();
        *send_stream << "cool stuff";
        wsServer.send(connection, send_stream, [](const boost::system::error_code& ec)
        {
            if (ec) {
                std::cout << "Server: Error sending message. " <<
                    "Error: " << ec << ", error message: " << ec.message() << std::endl;
            }
        });

Thoughts?

Multiple connections

I'm not sure why I would be getting this issue, but if I have multiple simultaneous connections, onmessage seems to all be directed on to the last connection, and not the connection it originated from.

Is there something wrong with my code?

Boost.Coroutine is now deprecated. Please switch to Boost.Coroutine2.

Hello, and thank you for maintaining this project--it has been really helpful for me.

Since upgrading to Boost 1.62, I now get this warning:

  CL : warning : Boost.Coroutine is now deprecated. Please switch to Boost.Coroutine2. To disable this warning message, define BOOST_COROUTINES_NO_DEPRECATION_WARNING. 

It's not causing me any trouble, but I thought you might like to know.

possible race condition on message send

When sending multiple (large) messages, oftentimes the send fails with odd messages about protocol corruption.

Haven't dug into the code too deeply, but it seems this can be a possible issue. Any thoughts for workarounds?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.