1 /*----------------------------------------------------------------------------
2 Name: CallbackServerUnparsed.h
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Include this header in your client code if you want to establish
6 a client side callback server.
7 We will call the update() method when messages arrive.
8 The received message key and QoS is not parsed, we need another
9 layer doing XML parsing with expat.
10 This library is thread safe, multiple client callback servers may
11 be established in parallel.
12 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info>
13 Date: 05/2003
14 See: http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.html
15 -----------------------------------------------------------------------------*/
16 #ifndef XMLBLASTER_CallbackServerUnparsed_H
17 #define XMLBLASTER_CallbackServerUnparsed_H
18
19 #ifdef __cplusplus
20 #ifndef XMLBLASTER_C_COMPILE_AS_CPP /* 'g++ -DXMLBLASTER_C_COMPILE_AS_CPP ...' allows to compile the lib as C++ code */
21 extern "C" {
22 #endif
23 #endif
24
25 #include <util/msgUtil.h>
26 #include <util/Properties.h>
27 #include "socket/xmlBlasterSocket.h"
28
29 #define DEFAULT_CALLBACK_SERVER_PORT 7611
30
31 /* Forward declarations */
32 struct SocketDataHolder;
33 struct CallbackServerUnparsedStruct;
34 typedef struct CallbackServerUnparsedStruct CallbackServerUnparsed;
35
36 /* Define function pointers */
37
38 /**
39 * Use this function directly after creation of the callback server
40 * if you want to force to reuse the given socket for callbacks.
41 *
42 * @param socketToUse Usually pass -1 so that we establish a callback server, else
43 * pass an opened socket (e.g. from XmlBlasterConnectionUnparsed->socketToXmlBlaster)
44 * @param socketToUseUdp Usually pass -1 so that we establish a callback server, else
45 * pass an opened socket (e.g. from XmlBlasterConnectionUnparsed->socketToXmlBlaster)
46 * @return true on success
47 */
48 typedef bool (* UseThisSocket)(CallbackServerUnparsed *cb, int socketToUse, int socketToUseUdp);
49
50 typedef int (* InitCallbackServer)(CallbackServerUnparsed *cb);
51
52 /**
53 * @return true if the socket is open and waits for callback messages
54 */
55 typedef bool (* IsListening)(CallbackServerUnparsed *cb);
56
57 /**
58 * Only in pthread_detach() mode
59 */
60 typedef bool (* WaitOnCallbackThreadTermination)(CallbackServerUnparsed *cb, long millis);
61 typedef bool (* WaitOnCallbackThreadAlive)(CallbackServerUnparsed *cb, long millis);
62
63 /**
64 * Here we asynchronously receive the callback from xmlBlaster.
65 *
66 * NOTE: After this call the memory of #MsgUnitArr is freed immediately by #CallbackServerUnparsed
67 * So you need to take a copy of all message members if needed out of the scope of this function.
68 *
69 * @param msgUnitArr The messages from the server, use MgsUnit#responseQos to transport the return value
70 * @param userData An optional pointer from the client with client specific data which is delivered back
71 * @param xmlBlasterException This points on a valid #XmlBlasterException struct, so you only need to fill errorCode with strcpy()
72 * and the returned pointer is ignored and the exception is thrown to xmlBlaster.
73 * @param socketDataHolder #SocketDataHolder containing socket specific informations, please handle as readonly
74 * @return Return true if everything is OK
75 * Return false if you want to throw an exception, please fill xmlBlasterException in such a case.
76 * If false and *xmlBlasterException.errorCode==0 we don't send a return message (useful for update dispatcher thread to do it later)
77 * @see http://www.xmlblaster.org/xmlBlaster/doc/requirements/interface.update.html
78 */
79 typedef void (*UpdateCbFp)(MsgUnitArr *msg, void *userData, XmlBlasterException *xmlBlasterException, void/*SocketDataHolder*/ *socketDataHolder);
80
81 typedef void (* ShutdownCallbackServerRaw)(CallbackServerUnparsed *cb);
82
83 typedef void ( * CallbackServerUnparsedSendResponse)(CallbackServerUnparsed *cb, void/*SocketDataHolder*/ *socketDataHolder, MsgUnitArr *msgUnitArr);
84 typedef void ( * CallbackServerUnparsedSendXmlBlasterException)(CallbackServerUnparsed *cb, void/*SocketDataHolder*/ *socketDataHolder, XmlBlasterException *exception);
85 typedef void ( * CallbackServerUnparsedDoRespond)(XMLBLASTER_C_bool success, CallbackServerUnparsed *cb, void/*SocketDataHolder*/ *socketDataHolder, MsgUnitArr *msgUnitArrP, XmlBlasterException *exception);
86
87 #define MAX_RESPONSE_LISTENER_SIZE 100
88
89 typedef void (* ResponseFp)(MsgRequestInfo *msgRequestInfoP, void /*SocketDataHolder*/ *socketDataHolder); /* using void * to avoid including the socket specific header */
90
91 typedef struct ResponseListenerStruct {
92 MsgRequestInfo *msgRequestInfoP;
93 /*void *userP;
94 const char *requestId;*/
95 ResponseFp responseEventFp;
96 } ResponseListener;
97
98 typedef bool ( * AddResponseListener)(CallbackServerUnparsed *cb, MsgRequestInfo *msgRequestInfoP, ResponseFp responseEventFp);
99 typedef ResponseListener * ( * RemoveResponseListener)(CallbackServerUnparsed *cb, const char *requestId);
100
101 typedef void ( * CallbackServerUnparsedLogging)(void *logUserP, XMLBLASTER_LOG_LEVEL currLevel, XMLBLASTER_LOG_LEVEL level, const char *location, const char *fmt, ...);
102
103 /**
104 * This structure holds a complete callback server instance.
105 *
106 * The function pointers like #isListening() allow you to
107 * invoke methods on this structure.
108 * <p>
109 * The function pointer #updateCb() holds the clients callback function
110 * which is invoked when messages arrive. See the description of #UpdateCbFp.
111 * </p>
112 */
113 struct CallbackServerUnparsedStruct {
114 Properties *props;
115 bool stopListenLoop;
116 int listenSocket;
117 int acceptSocket;
118 int socketUdp;
119 char * hostCB;
120 int portCB;
121 bool reusingConnectionSocket; /**< is false if we tunnel callback through the client connection socket */
122 XMLBLASTER_LOG_LEVEL logLevel;
123 CallbackServerUnparsedLogging log;
124 void *logUserP; /**< For outside users to pass a user object back to their logging implementation */
125 WaitOnCallbackThreadAlive waitOnCallbackThreadAlive;
126 WaitOnCallbackThreadTermination waitOnCallbackThreadTermination;
127 /*
128 * Is created by the client and used to validate callback messages in update.
129 * This is sent on connect in ConnectQos.
130 * (Is different from the xmlBlaster secret session ID)
131 char secretSessionId[MAX_SECRETSESSIONID_LEN];
132 */
133 InitCallbackServer runCallbackServer;
134 IsListening isListening;
135 ShutdownCallbackServerRaw shutdown; /**< For internal use (multi thread) only */
136 UpdateCbFp updateCb;
137 void *updateCbUserData; /**< A optional pointer from the client code which is returned to the update() function call */
138 UseThisSocket useThisSocket;
139 ResponseListener responseListener[MAX_RESPONSE_LISTENER_SIZE];
140 AddResponseListener addResponseListener;
141 RemoveResponseListener removeResponseListener;
142 bool _threadIsAliveOnce; /**< Mark if thread is running (is never reset if once on true!) */
143 bool threadIsAlive; /**< Lifecycle of thread */
144 CallbackServerUnparsedSendResponse sendResponse;
145 CallbackServerUnparsedSendXmlBlasterException sendXmlBlasterException;
146 CallbackServerUnparsedDoRespond sendResponseOrException;
147 pthread_mutex_t listenMutex;
148
149 /* Socket write access: */
150 XmlBlasterWriteToSocketFuncHolder writeToSocket; /**< The function pointer to write n bytes of plain or compressed data to the socket
151 Is initialized in initConnection(), outside users may choose to initialize it to some other function pointer */
152
153 /* Socket read access: */
154 XmlBlasterReadFromSocketFuncHolder readFromSocket; /**< Holding function pointer for compressed/uncompressed socket reads */
155
156 #ifdef XB_USE_PTHREADS
157 pthread_mutex_t responseListenerMutex; /* Needed for responseListener access protection */
158 #endif
159 };
160
161 /**
162 * Auxiliary struct for passing parameters to listening threads
163 */
164 typedef struct ListenLoopArgsStruct {
165 CallbackServerUnparsed* cb;
166 bool udp;
167 } ListenLoopArgs;
168
169 /**
170 * Get a new instance of a callback server struct.
171 * This is usually the first call of a client, you need to call #runCallbackServer()
172 * on the returned pointer to establish a listener.
173 * @param argc Number of command line arguments
174 * @param argv The command line arguments
175 * @param updateCb The function pointer on your update() function which handles the received messages
176 * Please read the documentation of #UpdateCbFp above.
177 * @param userData An optional pointer from the client with client specific data
178 * which is delivered back with the updateCb() function
179 * @return NULL if allocation or bootstrapping failed. If not NULL you need to free() it when you are done
180 * usually by calling freeXmlBlasterConnectionUnparsed().
181 */
182 extern CallbackServerUnparsed *getCallbackServerUnparsed(int argc, const char* const* argv,
183 UpdateCbFp updateCb, void *userData);
184
185 /**
186 * free() the CallbackServerUnparsed structure and sets *callbackData to 0
187 * Call freeCallbackServerUnparsed(&cb);
188 */
189 extern void freeCallbackServerUnparsed(CallbackServerUnparsed **callbackData);
190
191 /**
192 * Help on configuration
193 */
194 extern const char *callbackServerRawUsage(void);
195
196 /*
197 * Function pointer for pthread,
198 * the method to invoke on thread creation.
199 *
200 typedef void * (*CallbackFp)(void *);
201 */
202
203 #ifdef __cplusplus
204 #ifndef XMLBLASTER_C_COMPILE_AS_CPP
205 }
206 #endif
207 #endif
208
209 #endif /* XMLBLASTER_CallbackServerUnparsed_H */
syntax highlighted by Code2HTML, v. 0.9.1