//----------------------------------------------------------------------------- // Copyright (c) 1994,1995 Southeastern Universities Research Association, // Continuous Electron Beam Accelerator Facility // // This software was developed under a United States Government license // described in the NOTICE file included as part of this distribution. // //----------------------------------------------------------------------------- // // Description: // RSVC Client Handler Class // // Limitation on monitor: Callers cannot use same function with same user // argument to monitor on different pieces // of database // // Author: Jie Chen // // // #ifndef _RSVC_CLIENT_H #define _RSVC_CLIENT_H #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include #include #include #include #include class rsvcClientLocker; class RSVC_CLASS_SPEC rsvcClient { public: // constructor rsvcClient (void); ~rsvcClient (void); // connect to a rsvc server // if timeout is zero, blocked connect will be used int connect (char* host, unsigned short port, double timeout = 0.0); // disconnect from the server int disconnect (void); // return whether this client is connected int connected (void); // register a disconnect callback int disconnectCallback (rsvcCbkFunc func, void* arg); // get tcp file descriptor int getFd (void) const; // pend io on this connected client // Wait until outstanding events occur // seconds = 0.0 polling int pendIO (double seconds); // wait on this connection forever int pendIO (void); // operations // create a table with definition defined in the data object // the data object has to contain the following tags // "key" "name" // "keyExp" "attributename" or "attr0+attr1" // "keyType" anything // followed by taged values // data return from server inside callback is the database definition int createMemDbase (char* tablename, rsvcData& data, rsvcCbkFunc func, void* arg); // open a database // data return from server inside callback is the database definition int openDatabase (char* tablename, rsvcData& data, rsvcCbkFunc func, void* arg); // insert data into database // data must be match table definition int insertValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg, int overwrite = 0); // get data out from database // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int getValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // delete data from database // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int delValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // set value for a datum inside database // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value // plus a subset of tagged values defined in the table definition int setValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor incoming entries inside database // any insertion to a database will trigger a callback int monitorIncomingEntries (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // stop monitoring the incoming entries inside database int monitorOffIncomingEntries (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor on a data inside a database // any changes to this data will trigger a callback // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int monitorValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor off on a data inside a database // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int monitorOffValue (char* name, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor a single attribute of a data inside a database // any changes to this attribute will trigger a callback containing a whole data // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int monitorAttr (char* name, char* attrname, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor a single attribute of a data inside a database // any changes to this attribute will trigger a callback containing a whole data // data either contain a tagged value to denote a index value // Example: "id", "model+gold" // or contains multiple tagged values which can be constructed // into a key value int monitorOffAttr (char* name, char* attrname, rsvcData& data, rsvcCbkFunc func, void* arg); // query a particular database 'name' // query msg can be like regular C logic expression for all // attributes int query (char* name, char* qmsg, rsvcCbkFunc func, void* arg); // test purpose only void shutdownServer (void); protected: // non block tcp connect static int connect_nonblock (int fd, struct sockaddr* addr, size_t addrlen, struct timeval* timeout); // cleanup all callbacks void cleanupCallbacks (void); // call all disconnection callbacks void callAllDiscCbks (void); // stream out a network data and return actual number of bytes int streamData (rsvcNetData& data); // low level handle input and handle close int handle_input (int fd); int handle_close (int fd); // read and write for block socket static int read_n (int fd, char* buffer, size_t len); static int write_n (int fd, const char* buffer, size_t len); // real processing function int processData (rsvcNetData& data); // real command callback int commandCallback (int opcode, rsvcData& data, rsvcCbkFunc func, void* arg); // monitor command callback int monitorCallback (int opcode, rsvcData& data, rsvcCbkFunc func, void* arg); // monitoroff command callback int monitorOffCallback (int opcode, rsvcData& data, rsvcCbkFunc func, void* arg); // handle callbacks from server int cmdCbkFromServer (int status, rsvcData& data, rsvcCbk& cbk); int monitorCbkFromServer (int status, rsvcData& data, rsvcCbk& cbk); // check a monitor callback is in the table rsvcCbk* monitorCbkInTable (rsvcCbkFunc func, void* arg); private: // flag of connection int connected_; // tcp socket to the server int tcp_fd_; // server information char* server_host_; unsigned short server_port_; // lock for client object to prevent from this object being called // recursivly int lock_; void lock (void); void unlock (void); // request id int reqid_; // unique callback id int cbkid_; // disconnection callback list rsvcSlist discCbkList_; // all send/get command callback list rsvcSlist cmdCbkList_; // all monitor callback list rsvcHash monitorCbkTable_; // data convertion buffer char* cbuffer_; size_t cbuflen_; // friend class friend class rsvcClientLocker; friend class rsvcDBHandler; // deny copy and assignment operator rsvcClient (const rsvcClient& client); rsvcClient& operator = (const rsvcClient& client); }; class rsvcClientLocker { public: rsvcClientLocker (rsvcClient* client); ~rsvcClientLocker (void); private: rsvcClient* cl_; // deny copy and assignment operations rsvcClientLocker (const rsvcClientLocker& locker); rsvcClientLocker& operator = (const rsvcClientLocker& locker); }; #endif