When I use CAsyncSocket, can I reuse the same object for another connection (by closing and opening again), or should I create a brand-new object for each connection?
The socket can be reused but it often takes a couple of minutes before it will work. So you should create a new object for each connection.
Related
I'm working with QT UDP Sockets. This Socket are part of a "communication" class called, say, Com. It happens, for the needs of my application, that Com need to be deleted. Now, my question is: is it sufficient to invoke delete myUdpSocket; or should I explicitly invoke flush(), 'close()` or whatever? I ask this because when I delete Com the application does not necessairly need to close but instead it it possible that a new Instance of om need to be instantiated and with that a new instance of a UDP Socket on the same port and at the same addresses.
Yes, deleting the QUdpSocket will close it (and unbind) automatically.
This means that you can create a new instance later on the same port and address.
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.
I am looking for a unique logging solution using the POCO C++ library.
I will try to explain our design and the issue we are facing.
We have a TCPServerConnectionFactory that spawns a new environment (new set of objects) with each new connection. The spawned environment gets a new socket and has a listening thread. If a message comes in to an established connection a pthread will handle the message. Each useful message that comes in will contain an identifier that will identify all actions that happen until this process is completed by closing the connection and destructing the set of objects that were created for this connection.
Many connections may happen simultaneously. Before moving to a pthreaded environment we were able to use Thread::setName along with the %T identifier to clearly see which log messages were coming from which connection. Now that we are multi-threaded we need a new solution.
I have been unable to find a clean way to make each object that gets spawned through the life of a connection aware of our unique identifier. A global would get overwritten by a new transaction. Passing the ID to each new object would be messy.
My next attempt was to use the POCO Logger channel framework to save each connection's logs to a new file named by the unique identifier we would receive in a message. The issue here is that if a new connection comes in during the life of another, it will overwrite the channel properties and start pointing logs to a different file.
Using the Logger framework, is there a way for me to have a new Logger hierarchy per connection? Basically, we need the set of objects spawned by the new connection to all use the same logging properties, and to not affect any other set of objects logging properties.
Any insight as to a proper way to share the identifier among all objects created during the life of a connection would be useful as well.
Thanks!
If you want to store tiny amounts of information then use a singleton instance of your logger along with a mutex and a semaphore to avoid deadlock / livelock issues.But if you're expecting lots of connections, blocking on the mutex would slow things down therefore you should consider using 1 logger instance per connection.
In case you're going singleton consider using std::mutex since it has built-in deadlock protection.
I have a server application with such structure:
There is one object, call him Server, that in endless cycle listens and accepts connections.
I have descendant class from CAsyncSocket, that has overriden event OnReceive, call him ProxySocket.
Also I have a thread pool with early created threads.
When connection is received by server object he accepts the new connection on the new object ProxySocket.
When data arrives to the ProxySocket, he creates a command object and gives it to thread pool. In this command object I giving the socket handle of a ProxySocket. When new object of command is creating - I creating a new Socket in working thread and attach handle to it.
My issue is next:
When command ends, socket doesn't close, I just detach handle it and set CSocket handle to INVALID_SOCKET value, as planned. But my first ProxySocket object doesn't receives messages of new data receiving after that. How can I solve this?
I don't think you can use CAsyncSocket objects (or their descendants) in a thread pool secenario. CAsyncSockets are implemented on top of WSASsyncSelect - which tells the winsock to send notifcations to a window handle.
Because windows have thread affinity, one can never "move" the CAsyncSocket handling to a different thread.
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).