Add command output string and client/server response.

This commit is contained in:
athile 2010-07-01 15:50:24 -07:00
parent d44f322b8a
commit 7cc27d9b66
8 changed files with 172 additions and 60 deletions

View file

@ -0,0 +1,19 @@
#ifndef COMMANDSERVER_COMMAND_HPP
#define COMMANDSERVER_COMMAND_HPP
namespace OMW
{
///
/// A Command is currently defined as a string input that, when processed,
/// will generate a string output. The string output is passed to the
/// mReplyFunction as soon as the command has been processed.
///
class Command
{
public:
std::string mCommand;
boost::function1<void, std::string> mReplyFunction;
};
}
#endif COMMANDSERVER_COMMAND_HPP

View file

@ -9,6 +9,12 @@ using boost::asio::ip::tcp;
//
namespace OMW { namespace CommandServer { namespace Detail {
struct Header
{
char magic[4];
size_t dataLength;
} header;
///
/// Tracks an active connection to the CommandServer
///
@ -19,7 +25,9 @@ namespace OMW { namespace CommandServer { namespace Detail {
void start();
void stop();
tcp::socket& socket();
void reply (std::string s);
protected:
void handle ();
@ -53,18 +61,29 @@ namespace OMW { namespace CommandServer { namespace Detail {
{
return mSocket;
}
void Connection::reply (std::string reply)
{
const size_t plen = sizeof(Header) + reply.length() + 1;
std::vector<char> packet(plen);
Header* pHeader = reinterpret_cast<Header*>(&packet[0]);
strncpy(pHeader->magic, "OMW0", 4);
pHeader->dataLength = reply.length() + 1; // Include the null terminator
strncpy(&packet[8], reply.c_str(), pHeader->dataLength);
boost::system::error_code ec;
boost::asio::write(mSocket, boost::asio::buffer(packet),
boost::asio::transfer_all(), ec);
if (ec)
std::cout << "Error: " << ec.message() << std::endl;
}
void Connection::handle ()
{
bool bDone = false;
while (!bDone)
{
struct Header
{
char magic[4];
size_t dataLength;
} header;
// Read the header
boost::system::error_code error;
mSocket.read_some(boost::asio::buffer(&header, sizeof(Header)), error);
@ -79,7 +98,7 @@ namespace OMW { namespace CommandServer { namespace Detail {
boost::system::error_code error;
mSocket.read_some(boost::asio::buffer(&msg[0], header.dataLength), error);
if (!error)
mpServer->postMessage( &msg[0] );
mpServer->postCommand(this, &msg[0]);
else
bDone = true;
}
@ -98,10 +117,10 @@ namespace OMW { namespace CommandServer {
using namespace Detail;
Server::Server (Deque* pDeque, const int port)
: mAcceptor (mIOService, tcp::endpoint(tcp::v4(), port))
, mpCommands (pDeque)
, mbStopping (false)
Server::Server (Deque* pCommandQueue, const int port)
: mAcceptor (mIOService, tcp::endpoint(tcp::v4(), port))
, mpCommandQueue (pCommandQueue)
, mbStopping (false)
{
}
@ -149,9 +168,12 @@ namespace OMW { namespace CommandServer {
delete ptr;
}
void Server::postMessage (const char* s)
void Server::postCommand (Connection* pConnection, const char* s)
{
mpCommands->push_back(s);
Command cmd;
cmd.mCommand = s;
cmd.mReplyFunction = std::bind1st(std::mem_fun(&Connection::reply), pConnection);
mpCommandQueue->push_back(cmd);
}
void Server::threadMain()

View file

@ -9,6 +9,7 @@
#include <boost/thread.hpp>
#include "components/misc/tsdeque.hpp"
#include "components/commandserver/command.hpp"
namespace OMW { namespace CommandServer
{
@ -27,9 +28,9 @@ namespace OMW { namespace CommandServer
class Server
{
public:
typedef TsDeque<std::string> Deque;
typedef TsDeque<Command> Deque;
Server (Deque* pDeque, const int port);
Server (Deque* pCommandQueue, const int port);
void start();
void stop();
@ -39,7 +40,7 @@ namespace OMW { namespace CommandServer
typedef std::set<Detail::Connection*> ConnectionSet;
void removeConnection (Detail::Connection* ptr);
void postMessage (const char* s);
void postCommand (Detail::Connection*, const char* s);
void threadMain();
@ -53,8 +54,8 @@ namespace OMW { namespace CommandServer
ConnectionSet mConnections;
mutable boost::mutex mConnectionsMutex;
// Pointer to output queue in which to put received strings
Deque* mpCommands;
// Pointer to command queue
Deque* mpCommandQueue;
};
}}