I'm trying to enable multiple simultaneous client access to a webservice, enabeling a client to make a request and block until data is available (I am doing it this way since gsoap does not support notifications)
My webservice class is compiled with WITH_PURE_VIRTAL, meaning that I can't create instances of it, as it is an abstract class. Thus, I use one class built by me, which inherits from the webservice class, and is responsible for managing the webservice and webclient requests.
However, when my class is busy handling an existent client, I can't seem to receive any other requests.
I read (here) that you should launch a thread with something similar to this:
soap_serve((struct soap*)soap);
soap_destroy((struct soap*)soap); // dealloc C++ data
soap_end((struct soap*)soap); // dealloc data and clean up
soap_done((struct soap*)soap); // detach soap struct
free(soap);
However, when I modify the that code to call my webservice class instead, the serve call doesn't do anything.
I also tried launching a new thread inside my webservice call methods, but as soon as the thread launches, the webclient receives an empty response.
Does anyone have any suggestions?
If you look at my answer to this question you can see a very basic C++ threaded gSoap server. What I think you may be missing is the need to copy the service class, in my code the line tc = c.copy() ; // make a safe copy this copies the gSoap service instance including the gSoap context; it's this copy that's passed into the new thread so that the new thread can respond to the request while the main thread waits for another request to be made.
Related
My web app is based on (embedded) Jetty 9. The code that runs inside Jetty (i.e. from the *.war file) has the need to, at times, execute an HTTP request back into Jetty and itself, completely asynchronously to "real" HTTP requests coming from the network.
I know what you will say, but this is the situation I ended up with after merging multiple disparate products into one container and presently cannot avoid it. A stop-gap measure is in place - it actually sends a network HTTP request back to itself (presently using Jetty client, but that does not matter). However, not only that adds more overhead, it also does not allow us to pass actual object references we'd like to be able to pass via, say, request attributes.
Desire is to be able to do something like constructing new HttpServletRequest and HttpServletResponse pair and use a dispatcher to "include" (or similar) the other servlet we presently can only access via the network. We've built "dummy" implementations of those, but the this fails in Jetty's dispatcher line 120 with a null pointer exception:
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
{
Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest();
... because this is not an instance of Jetty's Request class and getCurrentHttpChannel() returns null because the thread is a worker thread, not an http serving one and does not have Jetty's thread locals set up.
I am contemplating options, but would like some guidance if anyone can offer it. Some things I am thinking of:
Actually use Jetty's Request class as a base. Currently not visible to the web app (a container class, would have to play with classpath and class loaders perhaps. May still be impossible (don't know what to expect there).
Play with Jetty's thread locals, attempt to tell Jetty to set up current thread as necessary. Don't know where to begin. UPDATE Tried to setServerClasses([]) and then set the current HttpChannel to the one I 'stole' from another thread. Failed misearably: java.lang.IllegalAccessError: tried to access method org.eclipse.jetty.server.HttpChannel.setCurrentHttpChannel(Lorg/eclipse/jetty/server/HttpChannel;)V from class ...
Ideally, find a better/proper way of feeding a "top" request in without going via the network. Ideally would execute on the same thread, but I would be less concerned with that.
Remember that, unfortunately, I cannot avoid this at this time. I would much rather invoke code directly, but I cannot, as the code I had to add into mine is too big to handle at this time and too dependent on some third party filters I can't even modify (and only work as filters, on real requests).
Please help!
I have an out of process ATL COM server (exe). When it is started by a Client the server spawns a worker thread which polls for some data. Every time the data is updated I want to notify all of the clients with the updated value.
I have created a COM Client, which connects via CoCreateInstanceEx, creates its Sink object, gets the connection point and calls Advise, all without error. However, When the server tries to Fire_event, it's IConnectionPointImpl::m_vec is empty and no clients are ever notified.
I assume this is because the server creates its own object, so I end up with two instances of IConnectionPointImpl::m_vec, one from the server and one from the client when it calls Advise. How can I get the server data to the clients?
I'd recommend this approach. Create a plain vanilla C++ singleton (not a COM object) - let's call it S. S would hold a list of weak, non-AddRef'ed references to all outstanding COM objects (a C++ class pointer, rather than a COM interface pointer, would be convenient). Your COM objects would register themselves with S in their constructor, and deregister in destructor.
When something interesting happens, your worker thread would notify (call a method on) S, which would notify all registered COM objects, which would call Fire_event on themselves.
Be careful when firing events from a worker thread. This is illegal, unless both your main thread and worker thread enter MTA. See http://vcfaq.mvps.org/com/1.htm for details and some workarounds.
Hi I have a QNetworkAccessManager which I use to send request to get image data from server. This call is asynchronous. I do multiple calls with it. Each call is done by opening a new instance of QNetworkAccessManager So when a specific condition occurs I want to stop the QNetworkAccessManager from receiving the replies from its network requests. Is there any way to do it? Thanks.
Don't use a new QNetworkAccessManager for each request but share the manager. It's usually fine to have just one. Of course one can have multiple if the application design suggests it - but e.g. managing multiple of them in a single controlling object is usually unnecessary. Just have one manager with the same lifetime as the object controlling the network requests.
To cancel running operations, keep the QNetworkReply* pointers QNetworkAccessManager::get/put/post return and call abort() when your condition occurs.
Connect to the finished() signal to remove them from the bookkeeping (as otherwise you would end up with dangling pointers).
If that becomes too complicated, think about using the command pattern. In this answer I describe why I find it particularly useful in this context.
I am using boost::asio to implement network programming and running into timing issues. The issue is currently most with the client.
The protocol initially begins by the server returning a date time string to the user, and the client reads it. Up to that part it works fine. But What I also want is to be able to write commands to the server which then processes them. To accomplish this I use the io_service.post() function as shown below.
io_service.post(boost::bind()); // bounded function calls async_write() method.
For some reason the write tries happens before the initial client/server communication, when the socket has not been created yet. And I get bad socket descriptor error.
Now the io_service's run method is indeed called in another thread.
When I place a sleep(2) command before post method, it work fine.
Is there way to synchronize this, so that the socket is created before any posted calls are executed.
When creating the socket and establishing the connection using boost::asio, you can define a method to be called when these operations have either completed or failed. So, you should trigger your "posted call" in the success callback.
Relevant methods and classes are :
boost::asio::ip::tcp::resolver::async_resolve(...)
boost::asio::ip::tcp::socket::async_connect(...)
I think the links below
will give u some help
http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/io_service.html
I am designing a game server with scripting capabilities. The general design goes like this:
Client connects to Server,
Server initializes Client,
Server sends Client to EventManager (separate thread, uses libevent),
EventManager receives receive Event from Client socket,
Client manages what it received via callbacks.
Now the last part is what's the most tricky for me now.
Currently my design allows me for a class which inherits Client to create callbacks to specific received events. These callbacks are managed in a list and the received buffer goes through a parsing process each time something is received. If the buffer is valid, the callback is called where it is act upon what is in the buffer. One thing to note is that the callbacks can go down to the scripting engine, at which point nothing is sure what can happen.
Each time a callback finishes, the current receive buffer has to be reset etc. Callbacks currently have no capability of returning a value, because as stated before, anything can happen.
What happens is that when somewhere in the callback something says this->disconnect(), I want to immediately disconnect the Client, remove it from the EventManager, and lastly remove it from the Server, where it also should get finally destructed and free memory. However, I still have some Code running after the callback finishes in the Client, thus I can't free memory.
What should I change in the design? Should I have some timed event in the Server which checks which Clients are free to destroy? Would that create additional overhead I don't need? Would it still be okay after the callback finishes to run minimal code on the stack (return -1;) or not?
I have no idea what to do, but I am open for complete design revamps.
Thanks in advance.
You can use a reference counted pointer like boost::shared_ptr<> to simplify memory management. If the manager's client list uses shared_ptrs and the code that calls the callbacks creates a local copy of the shared_ptr the callback is called on, the object will stay alive until it is removed from the manager and the callback function is complete:
class EventManager {
std::vector< boost::shared_ptr<Client> > clients;
void handle_event(Event &event) {
// local |handler| pointer keeps object alive until end of function, even
// if it removes itselfe from |clients|
boost::shared_ptr<Client> handler = ...;
handler->process(event);
}
};
class Client {
void process(Event &event) {
manager->disconnect(this);
// the caller still holds a reference, so the object lives on
}
}
The Client object will automatically be deleted once the last shared_ptr to it goes out of scope, but not before. So creating a local copy of the shared_ptr before a function call makes sure the object is not deleted unexpectedly.
You should consider having an object like "Session" which will track particular message flow from start to finish (from 1 client).
This object should also take care of current state: primarily the buffers and processing.
Each event which triggers a callback MUST update the state of corresponding session.
Libevent is capable of providing you with any result of scheduled event: success, failure, timeout. Each of this types should be reflected with your logic.
In general, when working with events, consider your processing logic to be an automaton with a state.
http://en.wikipedia.org/wiki/Reactor_pattern may be a good resource for your task.
Let the Client::disconnect() function send an event to the EventManager (or Server) class. This means that you need some sort of event handling in EventManager (or Server), an event loop for instance.
My general idea is that Client::disconnect() does not disconnect the Client immediately, but only after the callback finished executing. Instead, it just posts an event to the EventManager (or Server) class.
One could argue that the Client::disconnect() method is on the wrong class. Maybe it should be Server::disconnect( Client *c ). That would be more in-line with the idea that the Server 'owns' the Client and it's the Server which disconnects Clients (and then updates some internal bookkeeping).