eidheim / Simple-WebSocket-Server

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++.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Non blocking stream

kenkit opened this issue · comments

Hi, thank you for this nice library, I'm doing a project using it. So far it works just as it's expected, however I'm stuck trying to create a nonblocking server stream.
I mean one that will not stop sending once the connection is opened.

Any help will be greatly appreciated.
Please include some code samples if you know how to do this.

		  echo.on_open = [](shared_ptr<WsServer::Connection> connection) {
			cout << "Server: Opened connection " << connection.get() << endl;
			
			while(1){
				auto send_stream2 = make_shared<WsServer::SendStream>();
				*send_stream2 <<"I am always sent";
				local_server.send(connection, send_stream2);
				cout<<"sent data"<<std::endl;
				
		
				
		  };

The above code doesn't do anything , but the loop works since I can see the console output "sent data"

I think there is a problem on this line. local_server.send(connection, send_stream2);

Fixed this, I used the clients echo.on_message to maintain a loop between and also did the same on the server side.

The way to do what you ask in an asynchronous environment is using an recursive function, for example:

WsServer server;
  server.config.port = 8080;

  auto &some_endpoint = server.endpoint["^/some_endpoint$"];
  some_endpoint.on_open = [](shared_ptr<WsServer::Connection> connection) {
    // Trick to define a recursive function within this scope (for your convenience):
    class MessageServer {
    public:
      static void wait_and_send(shared_ptr<WsServer::Connection> connection) {
        std::thread wait_and_send_thread([connection] {
          this_thread::sleep_for(chrono::seconds(1));
          auto message = make_shared<WsServer::SendStream>();
          *message << "some message";
          connection->send(message, [connection](const SimpleWeb::error_code &ec) {
            if(!ec)
              wait_and_send(connection);
          });
        });
        wait_and_send_thread.detach();
      }
    };
    MessageServer::wait_and_send(connection);
  };
  server.start();

The wait_and_send_thread is not needed of course, it was only added to add some delay between the messages.

edit: updated the example for the new 2.0 API

Thanks very much for your response, i just used a different method that will only send when the client requests some response.

In case someone tries this code:
I assume the server implementation has changed since the previous comment, but I could (I had to in fact) run it without capturing the server:

class MessageServer {
        public:
            static void wait_and_send(shared_ptr<WsServer::Connection> connection) {
              std::thread wait_and_send_thread([connection] {
                this_thread::sleep_for(chrono::seconds(1));
                auto message = make_shared<WsServer::SendStream>();
               *message << "some message";
                connection->send(message, [connection,em](const SimpleWeb::error_code &ec) {
                  if(ec) {
                    cout << "Server: Error sending message. " <<
                    "Error: " << ec << ", error message: " << ec.message() << endl;
                }
                else wait_and_send(connection);
            });    
            });
              wait_and_send_thread.detach();
          }
      };
      MessageServer::wait_and_send(connection);```

@jbodart Thank you. I updated my example as well.

nicely done. I actually built my implementation through that example, i'll update my code eventually.
I use 2 servers on the server. When a client connects it is awarded a new port via a message which it the switches to, both client and server will create a new thread to achieve this. The server can the connect to multiple clients at the same time and share the same info.