GithubHelp home page GithubHelp logo

Comments (13)

eidheim avatar eidheim commented on July 20, 2024

Yes, when doing heavy calculations you should create your own thread. It is safe to use client.send() in this thread when the work is done, since synchronisation is already done in the send function through strand::post. In general, the onmessage/onopen/... functions are in most use cases run in 1 thread through asio (if you specify 1 thread when constructing the Server/Client object), and one then does not have to worry about mutexes and locks inside these functions.

Regarding the pings, only answering on pings is implemented. If you need to initiate and send a ping, you would have to implement this as well for instance in a separate thread.

from simple-websocket-server.

eidheim avatar eidheim commented on July 20, 2024

I think I need to add that if you create a thread inside for instance onmessage, make sure you run std::thread::detach() so that asio can run other tasks while the thread is performing its task.

from simple-websocket-server.

rberlich avatar rberlich commented on July 20, 2024

Thanks for the comprehensive answer! I do not understand, though, why I would have to explicitly detach() the thread -- ASIO will not know about it, if my "std::thread m_t" would be a class variable, and my plan was indeed to let a thread-pool (not based on the websocket io_service) handle the processing. This way I could open more than one connection to the server in the presence of multiple cores and let multiple (usually single-threaded) workloads be processed in parallel. Both web-service clients (running in the same binary) could use the same threadpool.

from simple-websocket-server.

eidheim avatar eidheim commented on July 20, 2024

Never mind the comment on detach then, and sorry for the confusion. The important issue is that the onmessage/onopen/.. functions return without any significant delay, so that asio can perform other tasks. If you have your own thread pool doing the processing, and you use send() from that pool, it should not be a problem.

from simple-websocket-server.

rberlich avatar rberlich commented on July 20, 2024

Sorry, I should have made it clearer that I'm wrapping your webservice client into my own class with its own set of onmessage(), onopen() ... functions, which in turn have access to my (mostly thread-safe) class internals. These functions are then registered with your client. onmessage() implements a protocol between client and server, so I can ask for work or lay low for a while, while the server has no work for me.
Thanks again for your anwer!

from simple-websocket-server.

Victordmdb avatar Victordmdb commented on July 20, 2024

I'm trying to do the same whereas i'm calling send from a lambda function which i'm passing to a thread launched in onmessage, but it seems to hang.

This only happens if I detach. If I join it works fine.

from simple-websocket-server.

eidheim avatar eidheim commented on July 20, 2024

@Victordmdb Make sure you detach the thread you are creating in onmessage, as onmessage should return as soon as possible. Also make sure you capture the connection object and keep it alive as long as needed.

from simple-websocket-server.

Victordmdb avatar Victordmdb commented on July 20, 2024

@eidheim That's the issue, when I detach it will hang once my lambda callback tries to send through the connection (which is still open). I've double checked, the connection object is being captured correctly.

Do you maybe have an example of a threaded call from onmessage?

from simple-websocket-server.

Victordmdb avatar Victordmdb commented on July 20, 2024

I've tried to boil down my code. Is this correct?

WsServer server(port, 2);
auto& ep = server.endpoint["^/connect/?$"];

ep.onmessage = [&](std::shared_ptr<WsServer::Connection> connection, std::shared_ptr<WsServer::Message> message) {

  auto callback = [&](std::string data) {
    auto send_stream = std::make_shared<WsServer::SendStream>();
    send_stream  << data;
    server.send( connection, send_stream, [](const boost::system::error_code& ec){
      //It never reaches here
    });
  }

  std::thread th = std::thread{&myProg, std::ref(callback)};
  th.detach();
}

  std::thread server_thread([&server](){
    server.start();
  });

  server_thread.join();

from simple-websocket-server.

eidheim avatar eidheim commented on July 20, 2024

I have not tested this, but I would write it as follows:

WsServer server(port, 2);
auto& ep = server.endpoint["^/connect/?$"];

ep.onmessage = [&server](std::shared_ptr<WsServer::Connection> connection, std::shared_ptr<WsServer::Message> message) {
  std::thread th([&server, connection] {
    // time consuming calculation here
    auto send_stream = std::make_shared<WsServer::SendStream>();
    send_stream  << data;
    server.send( connection, send_stream, [](const boost::system::error_code& ec){
      // do something here
    });
  });
  th.detach();
};

server.start();

from simple-websocket-server.

Victordmdb avatar Victordmdb commented on July 20, 2024

@eidheim Alright, but my code requires a callback mechanism as it is itself rather complicated, so does the lambda callback structure above make sense?

from simple-websocket-server.

eidheim avatar eidheim commented on July 20, 2024

Make sure you copy the connection object, right now you pass it as reference. Also place the server_thread, server.start() and server_thread.join() outside of the onmessage function. Also consider the lifetime of the 'callback' object that you pass as reference to 'std::thread'. You can probably not use 'std::ref' on a local variable when leaving scope like you do in your code.

from simple-websocket-server.

Victordmdb avatar Victordmdb commented on July 20, 2024

Right, the 'server_thread, server.start() and server_thread.join()' issue was because i badly copied. I managed to fixed the issue by copying connection instead of making a reference, as you said.

Thanks!

from simple-websocket-server.

Related Issues (20)

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.