Overview
Features
Download
Documentation
Community
Add-Ons & Services

Poco::Net TCPServer event handler

Please post support and help requests here.

Poco::Net TCPServer event handler

Postby Vortex636 » 31 Jan 2013, 23:42

Hello !

First of all, I want to thank the creators and contributors of Poco Library, it is some of the most clean, elegant and comprehensible code I have ever seen.
Now, after all the ass kissing, I have a small question.

I'm trying to build a server application as part of my research, which involves receiving XML messages from an Apache server.
I have gotten some of the work out of the way, by creating classes which inherit from: ServerApplication, TCPServer, TCPServerConnection, ServerSocket, TCPServerConnectionFactory.
The code works fine, indeed it creates a listening socket and new connection objects are recognized when I connect via netcat.

What I would like to know, is how to proceed from here, using an Event-Handler approach for the following:
    Handling incoming (recv) data
    Handling connection time-out
    Handling connection errors/exceptions
    Handling send data
Last time I did network programming in Linux I used libev (libevent clone) which took that approach.
From a little digging I did I found out that maybe ServerReactor is what I am looking for?

Basically what I want is some form of selector/delegate/function pointer/etc which will be called when data is found or an error occurs on a connection.

Any advise on how to proceed is very much welcomed :-)
Vortex636
 
Posts: 5
Joined: 31 Jan 2013, 23:30

Re: Poco::Net TCPServer event handler

Postby alex » 01 Feb 2013, 04:59

SocketReactor will do what you are looking for; it's default select-based but it supports (e)poll(), if available on your platform. See the EchoServer example. As of 1.5.1, there is also multi-threaded version - ParallelSocketReactor.
alex
 
Posts: 1113
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Poco::Net TCPServer event handler

Postby Vortex636 » 01 Feb 2013, 23:19

Thank you very much for the reply.

I am looking in SocketReactor & SocketNotifications, but I have a silly question:

I am using code from both the Echo server and other examples, and although (I believe) I have done it correctly and without any errors whatsoever, I still do not get any notification of events.
When I run the server, I can see the ConnectionFactory working, New connections being created, the SocketReactor running, yet nothing when I try with netcat to echo a simple message.
I am obviously missing something.
Below is the code.

Daemon.hpp
Code: Select all
class Daemon : public ServerApplication
{
  public:
    Daemon();
    int main();
};


Daemon.cpp
Code: Select all
Daemon::Daemon()
{}

int Daemon::main()
{
    ServerSocket srv_sock(2222);   
    Reactor reactor;
    Thread thread;
    thread.start(reactor);
    ConnectionFactory *conFactory = new ConnectionFactory(reactor);
    Server *srv = new Server(conFactory,srv_sock,0);
    srv->start();
    waitForTerminationRequest();
    reactor.stop();
    thread.join();
    srv->stop();
    std::cout << "Stopping..." << std::endl;
    return Application::EXIT_OK;
}


Server.hpp
Code: Select all
class Server : public TCPServer
{
  public:
    Server(ConnectionFactory::Ptr,const ServerSocket&,TCPServerParams::Ptr);
};


Server.cpp
Code: Select all
Server::Server(ConnectionFactory::Ptr factory,const ServerSocket& socket,TCPServerParams::Ptr param)
: TCPServer(factory,socket,param)
{
  std::cout << this->threadName(socket) << std::endl;
}


ConnectionFactor.hpp
Code: Select all
class ConnectionFactory : public TCPServerConnectionFactory
{
  public:
    ConnectionFactory(Reactor &);
    TCPConnection * createConnection(const StreamSocket &);
    Reactor & _reactor;
};


ConnectionFactory.cpp
Code: Select all
ConnectionFactory::ConnectionFactory(Reactor &reactor)
  : TCPServerConnectionFactory(), _reactor(reactor)
{
  std::cout << "ConnectionFactory init" << std::endl;
}

TCPConnection * ConnectionFactory::createConnection(const StreamSocket & socket)
{
  std::cout << "ConnectionFactory: new TCP connection" << std::endl;
  return new TCPConnection(socket,_reactor);
}


TCPConnection.hpp
Code: Select all
class TCPConnection : public TCPServerConnection
{
  public:
    TCPConnection(const StreamSocket &, Reactor &);
    void run();
    void onSocketReadable(const AutoPtr<ReadableNotification>& pNf);
    void onSocketWritable(const AutoPtr<WritableNotification>& pNf);
    void onSocketShutdown(const AutoPtr<ShutdownNotification>& pNf);
    void onSocketError(const AutoPtr<ErrorNotification>& pNf);
    void onSocketTimeout(const AutoPtr<TimeoutNotification>& pNf);
   
  private:
    const StreamSocket & _socket;
    Reactor & _reactor;
};


TCPConnection.cpp
Code: Select all
void TCPConnection::onSocketReadable(const AutoPtr<ReadableNotification>& pNf)
{
  std::cout << "client socket readable" << std::endl;
}

void TCPConnection::onSocketWritable(const AutoPtr<WritableNotification>& pNf)
{
  std::cout << "client socket writable" << std::endl;
}

void TCPConnection::onSocketShutdown(const AutoPtr<ShutdownNotification>& pNf)
{
  std::cout << "shutdown notification" << std::endl;
}

void TCPConnection::onSocketError(const AutoPtr<ErrorNotification>& pNf)
{
  std::cout << "error notification" << std::endl;
}

void TCPConnection::onSocketTimeout(const AutoPtr<TimeoutNotification>& pNf)
{
  std::cout << "timeout notification" << std::endl;
}


However I do not get any notifications. at all.
Copying code from EchoServer, which I might add is a much simpler design, I do get notifications.
So what am I missing, what is the recommended way of going on about this?
Vortex636
 
Posts: 5
Joined: 31 Jan 2013, 23:30

Re: Poco::Net TCPServer event handler

Postby alex » 02 Feb 2013, 16:43

Vortex636 wrote:So what am I missing, what is the recommended way of going on about this?

Looks like you're mixing two "orthogonal" server models - reactor and thread-based. Reactor operates in non-blocking mode by looping over socket handles and sending event notifications. TCPServer framework operates in blocking mode, listening and launching a thread per request.

If you want to go with Reactor model, forget the TCPServer; look back at EchoServer example - no TCPServer there, only ServerSocket with underlying StreamSocket (i.e. a TCP socket). So, the Reactor framework (see Reactor Pattern for theoretical background) is the TCP server and there's no need for another one. If you want to further scale your reactor-based server with threads, consider ParallelSocketReactor.

Hope this helps.
alex
 
Posts: 1113
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Poco::Net TCPServer event handler

Postby Vortex636 » 02 Feb 2013, 19:44

Yes it helps a lot! I finally figured it out.
I went for the SocketReactor approach as its much cleaner for me to implement and because this is a research framework I doubt I will get a lot of traffic.
Out of curiosity how is ParallelSocketReactor different than running a SocketReactor on its own thread?
Is a new thread spawned upon a new Connection Handler object?
Vortex636
 
Posts: 5
Joined: 31 Jan 2013, 23:30

Re: Poco::Net TCPServer event handler

Postby alex » 04 Feb 2013, 06:30

Vortex636 wrote:Out of curiosity how is ParallelSocketReactor different than running a SocketReactor on its own thread?
Is a new thread spawned upon a new Connection Handler object?

ParallelAcceptor has a pool (size configurable, defaulting to number of processors) of reactors, each running in its own thread; threads are spawned at reactors (i.e. acceptor, since reactors are members thereof) creation.
alex
 
Posts: 1113
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Poco::Net TCPServer event handler

Postby Vortex636 » 04 Feb 2013, 22:41

I will give it a go, it seems very interesting.
Thank you very much for the help, very much appreciated!
Vortex636
 
Posts: 5
Joined: 31 Jan 2013, 23:30


Return to Support

Who is online

Users browsing this forum: No registered users and 1 guest

cron