2007-10-20 01:35:48 +02:00
|
|
|
// message.h
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../util/sock.h"
|
2007-11-18 03:10:00 +01:00
|
|
|
#include "protocol.h"
|
2007-10-20 01:35:48 +02:00
|
|
|
|
|
|
|
class Message;
|
|
|
|
|
|
|
|
class MessagingPort {
|
|
|
|
public:
|
|
|
|
enum { DBPort = 27017 };
|
|
|
|
|
2007-11-18 03:10:00 +01:00
|
|
|
/* channels: if you are a server you can pass ANYCHANNEL to indicate you never initiate a
|
|
|
|
msg to someone yourself. the default will assign a new channel id to the messagingport.
|
|
|
|
*/
|
|
|
|
enum { AUTOASSIGNCHANNEL = -1, ANYCHANNEL = -2 };
|
|
|
|
MessagingPort(int channel = AUTOASSIGNCHANNEL);
|
2007-10-20 01:35:48 +02:00
|
|
|
~MessagingPort();
|
|
|
|
|
2007-11-18 19:33:00 +01:00
|
|
|
void shutdown() { if( pc ) pc->shutdown(); pc = 0; }
|
|
|
|
|
2007-11-14 03:32:29 +01:00
|
|
|
void init(int myUdpPort = 0 );
|
2007-10-20 01:35:48 +02:00
|
|
|
|
|
|
|
/* it's assumed if you reuse a message object, that it doesn't cross MessagingPort's.
|
|
|
|
also, the Message data will go out of scope on the subsequent recv call.
|
|
|
|
*/
|
|
|
|
bool recv(Message& m);
|
|
|
|
void reply(Message& received, Message& response);
|
|
|
|
bool call(SockAddr& to, Message& toSend, Message& response);
|
2007-11-18 03:10:00 +01:00
|
|
|
void say(int channel, SockAddr& to, Message& toSend, int responseTo = -1);
|
|
|
|
void say(SockAddr& to, Message& toSend, int responseTo = -1) {
|
|
|
|
say(channel(), to, toSend, responseTo);
|
|
|
|
}
|
2007-10-20 01:35:48 +02:00
|
|
|
|
2007-11-18 03:10:00 +01:00
|
|
|
int channel() { return myChannel; }
|
2007-10-20 01:35:48 +02:00
|
|
|
private:
|
2007-11-18 03:10:00 +01:00
|
|
|
ProtocolConnection *pc;
|
2007-10-20 01:35:48 +02:00
|
|
|
UDPConnection conn;
|
2007-11-18 03:10:00 +01:00
|
|
|
int myChannel;
|
2007-10-20 01:35:48 +02:00
|
|
|
enum { BufSize = 64 * 1024 };
|
|
|
|
char buf[BufSize];
|
|
|
|
};
|
|
|
|
|
|
|
|
#pragma pack(push)
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
|
|
enum Operations {
|
|
|
|
opReply = 1, /* reply. responseTo is set. */
|
|
|
|
|
|
|
|
dbMsg = 1000, /* generic msg command followed by a string */
|
|
|
|
|
|
|
|
dbUpdate = 2001, /* update object */
|
|
|
|
dbInsert = 2002,
|
2007-10-30 10:50:14 +01:00
|
|
|
// dbGetByOID = 2003,
|
2007-10-20 01:35:48 +02:00
|
|
|
dbQuery = 2004,
|
2007-10-30 10:50:14 +01:00
|
|
|
dbGetMore = 2005,
|
|
|
|
dbDelete = 2006
|
2007-10-20 01:35:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct MsgData {
|
|
|
|
int len; /* len of the msg, including this field */
|
2007-11-18 03:10:00 +01:00
|
|
|
MSGID id; /* request/reply id's match... */
|
2007-10-20 01:35:48 +02:00
|
|
|
int responseTo; /* id of the message we are responding to */
|
|
|
|
int operation;
|
|
|
|
char _data[4];
|
|
|
|
|
|
|
|
int dataLen();
|
|
|
|
};
|
|
|
|
const int MsgDataHeaderSize = sizeof(MsgData) - 4;
|
|
|
|
inline int MsgData::dataLen() { return len - MsgDataHeaderSize; }
|
|
|
|
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
class Message {
|
|
|
|
public:
|
2007-11-18 03:10:00 +01:00
|
|
|
Message() { data = 0; freeIt = false; channel = -1000; }
|
2007-10-20 01:35:48 +02:00
|
|
|
~Message() { reset(); }
|
|
|
|
|
|
|
|
SockAddr from;
|
|
|
|
MsgData *data;
|
2007-11-18 03:10:00 +01:00
|
|
|
int channel;
|
|
|
|
|
|
|
|
// int channel() { return data->channel; }
|
2007-10-20 01:35:48 +02:00
|
|
|
|
|
|
|
void reset() {
|
|
|
|
if( freeIt && data )
|
|
|
|
free(data);
|
2007-11-05 17:29:12 +01:00
|
|
|
data = 0; freeIt = false;
|
2007-10-20 01:35:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setData(MsgData *d, bool _freeIt) {
|
|
|
|
assert( data == 0 );
|
|
|
|
freeIt = _freeIt;
|
|
|
|
data = d;
|
|
|
|
}
|
|
|
|
void setData(int operation, const char *msgtxt) {
|
|
|
|
setData(operation, msgtxt, strlen(msgtxt)+1);
|
|
|
|
}
|
|
|
|
void setData(int operation, const char *msgdata, int len) {
|
|
|
|
assert(data == 0);
|
|
|
|
int dataLen = len + sizeof(MsgData) - 4;
|
|
|
|
MsgData *d = (MsgData *) malloc(dataLen);
|
|
|
|
memcpy(d->_data, msgdata, len);
|
|
|
|
d->len = dataLen;
|
|
|
|
d->operation = operation;
|
|
|
|
freeIt= true;
|
|
|
|
data = d;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool freeIt;
|
|
|
|
};
|
|
|
|
|