1 /*----------------------------------------------------------------------------
2 Name: xmlBlaster/demo/c/socket/HelloWorld3.c
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Example for all remote method invocations.
6 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info>
7 Compile: cd xmlBlaster; build c
8 (Win: copy xmlBlaster\src\c\socket\pthreadVC2.dll to your PATH)
9 Manually:
10 cd xmlBlaster/src/c
11 gcc -g -Wall -pedantic -Wno-long-long -D_REENTRANT -I. -o HelloWorld3
12 ../../demo/c/socket/HelloWorld3.c util/?*.c socket/?*.c -pthread
13 Invoke: HelloWorld3 -help
14 See: http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html
15 -----------------------------------------------------------------------------*/
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <XmlBlasterAccessUnparsed.h>
20
21 /**
22 * Here we receive the callback messages from xmlBlaster
23 * @param msgUnitArr The received messages, it is freed by the call after this method ends
24 * @param userData Is the corresponding XmlBlasterAccessUnparsed * pointer
25 * @param exception An OUT parameter to transport back an exception
26 * @see UpdateFp in XmlBlasterAccessUnparsed.h
27 * @see UpdateFp in CallbackServerUnparsed.h
28 */
29 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
30 XmlBlasterException *exception)
31 {
32 size_t i;
33 bool testException = false;
34 XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData;
35
36 for (i=0; i<msgUnitArr->len; i++) {
37 char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
38 printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
39 xml);
40 xmlBlasterFree(xml);
41 msgUnitArr->msgUnitArr[i].responseQos =
42 strcpyAlloc("<qos><state id='OK'/></qos>");
43 /* Return QoS: Everything is OK */
44 }
45 if (testException) {
46 strncpy0(exception->errorCode, "user.clientCode",
47 XMLBLASTEREXCEPTION_ERRORCODE_LEN);
48 strncpy0(exception->message, "I don't want these messages",
49 XMLBLASTEREXCEPTION_MESSAGE_LEN);
50 return false;
51 }
52
53 if (xa->callbackMultiThreaded == true) {
54 /* publish from inside the update thread,
55 see -plugin/socket/multiThreaded true */
56 char *response = (char *)0;
57 MsgUnit msgUnit;
58 XmlBlasterException xmlBlasterException;
59 memset(&msgUnit, 0, sizeof(MsgUnit));
60 printf("[client] Publishing message 'HelloWorldCb from update thread' ...\n");
61 msgUnit.key = strcpyAlloc("<key oid='HelloWorldCb'/>");
62 msgUnit.content = strcpyAlloc("Some message payload");
63 msgUnit.contentLen = strlen(msgUnit.content);
64 msgUnit.qos =strcpyAlloc("<qos><persistent/></qos>");
65 response = xa->publish(xa, &msgUnit, &xmlBlasterException);
66 freeMsgUnitData(&msgUnit);
67 if (*xmlBlasterException.errorCode != 0) {
68 printf("[client] Caught exception in publish errorCode=%s, message=%s\n",
69 xmlBlasterException.errorCode, xmlBlasterException.message);
70 xa->disconnect(xa, 0, &xmlBlasterException);
71 freeXmlBlasterAccessUnparsed(xa);
72 exit(EXIT_FAILURE);
73 }
74 printf("[client] Publish success, returned status is '%s'\n", response);
75 xmlBlasterFree(response);
76 }
77
78 return true;
79 }
80
81 #if defined(WINCE)
82 int _tmain(int argc, _TCHAR** argv_wcs) { /* wchar_t==_TCHAR */
83 char **argv = convertWcsArgv(argv_wcs, argc);
84 #else
85 /**
86 * Invoke: HelloWorld3 -logLevel TRACE
87 */
88 int main(int argc, const char* const* argv) {
89 #endif
90 int iarg;
91 char *response = (char *)0;
92 /*
93 * callbackSessionId:
94 * Is created by the client and used to validate callback messages in update.
95 * This is sent on connect in ConnectQos.
96 * (Is different from the xmlBlaster secret session ID)
97 */
98 const char *callbackSessionId = "topSecret";
99 XmlBlasterException xmlBlasterException;
100 XmlBlasterAccessUnparsed *xa = 0;
101 int sleepInterval = 0;
102
103 printf("[client] XmlBlaster %s C SOCKET client, try option '-help' if you need"
104 " usage informations\n", getXmlBlasterVersion());
105
106 for (iarg=0; iarg < argc; iarg++) {
107 if (strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "--help") == 0) {
108 char usage[XMLBLASTER_MAX_USAGE_LEN];
109 const char *pp =
110 "\n -sleepInterval Milliseconds to wait on callback messages [0]"
111 "\n\nExample:"
112 "\n HelloWorld3 -logLevel TRACE"
113 " -dispatch/connection/plugin/socket/hostname 192.168.2.9"
114 " -sleepInterval 100000";
115 printf("Usage:\nXmlBlaster C SOCKET client %s\n%s%s\n",
116 getXmlBlasterVersion(), xmlBlasterAccessUnparsedUsage(usage), pp);
117 exit(EXIT_FAILURE);
118 }
119 else if (strcmp(argv[iarg], "-sleepInterval") == 0 && iarg < argc-1)
120 sleepInterval = atoi(argv[++iarg]);
121 }
122
123 xa = getXmlBlasterAccessUnparsed(argc, (const char* const*)argv);
124 if (xa->initialize(xa, myUpdate, &xmlBlasterException) == false) {
125 printf("[client] Connection to xmlBlaster failed,"
126 " please start the server or check your configuration:\n%s %s\n",
127 xmlBlasterException.errorCode, xmlBlasterException.message);
128 freeXmlBlasterAccessUnparsed(xa);
129 exit(EXIT_FAILURE);
130 }
131
132 { /* connect */
133 char connectQos[2048];
134 char callbackQos[1024];
135 sprintf(callbackQos,
136 "<queue relating='callback' maxEntries='50000' maxEntriesCache='10000'>"
137 " <callback type='SOCKET' sessionId='%.120s'>"
138 " socket://%.120s:%d"
139 " </callback>"
140 "</queue>",
141 callbackSessionId, xa->callbackP->hostCB, xa->callbackP->portCB);
142 sprintf(connectQos,
143 "<qos>"
144 " <securityService type='htpasswd' version='1.0'>"
145 " <![CDATA["
146 " <user>fritz</user>"
147 " <passwd>secret</passwd>"
148 " ]]>"
149 " </securityService>"
150 " <session name='client/fritz' timeout='0' maxSessions='1'/>"
151 "%.1024s"
152 "</qos>", callbackQos);
153
154 response = xa->connect(xa, connectQos, myUpdate, &xmlBlasterException);
155 if (*xmlBlasterException.errorCode != 0) {
156 printf("[client] Caught exception during connect errorCode=%s, message=%s\n",
157 xmlBlasterException.errorCode, xmlBlasterException.message);
158 freeXmlBlasterAccessUnparsed(xa);
159 exit(EXIT_FAILURE);
160 }
161 xmlBlasterFree(response);
162 printf("[client] Connected to xmlBlaster, do some tests ...\n");
163 }
164
165 response = xa->ping(xa, 0, &xmlBlasterException);
166 if (response == (char *)0) {
167 printf("[client] ERROR: Pinging a connected server failed: errorCode=%s, message=%s\n",
168 xmlBlasterException.errorCode, xmlBlasterException.message);
169 freeXmlBlasterAccessUnparsed(xa);
170 exit(EXIT_FAILURE);
171 }
172 else {
173 printf("[client] Pinging a connected server, response=%s\n", response);
174 xmlBlasterFree(response);
175 }
176
177 { /* subscribe ... */
178 const char *key = "<key oid='HelloWorld'/>";
179 /*const char *key = "<key queryType='XPATH'>//key</key>";*/
180 const char *qos = "<qos/>";
181 printf("[client] Subscribe message 'HelloWorld' ...\n");
182 response = xa->subscribe(xa, key, qos, &xmlBlasterException);
183 if (*xmlBlasterException.errorCode != 0) {
184 printf("[client] Caught exception in subscribe errorCode=%s, message=%s\n",
185 xmlBlasterException.errorCode, xmlBlasterException.message);
186 xa->disconnect(xa, 0, &xmlBlasterException);
187 freeXmlBlasterAccessUnparsed(xa);
188 exit(EXIT_FAILURE);
189 }
190 printf("[client] Subscribe success, returned status is '%s'\n", response);
191 xmlBlasterFree(response);
192 }
193
194 if (sleepInterval > 0) {
195 printf("[client] Sleeping now and wait on 'HelloWorld' updates (start a publisher somewhere) ...\n");
196 sleepMillis(sleepInterval);
197 }
198
199 { /* publish ... */
200 MsgUnit msgUnit;
201 memset(&msgUnit, 0, sizeof(MsgUnit));
202 printf("[client] Publishing message 'HelloWorld' ...\n");
203 msgUnit.key = strcpyAlloc("<key oid='HelloWorld'/>");
204 msgUnit.content = strcpyAlloc("Some message payload");
205 msgUnit.contentLen = strlen(msgUnit.content);
206 msgUnit.qos =strcpyAlloc("<qos><persistent/></qos>");
207 response = xa->publish(xa, &msgUnit, &xmlBlasterException);
208 freeMsgUnitData(&msgUnit);
209 if (*xmlBlasterException.errorCode != 0) {
210 printf("[client] Caught exception in publish errorCode=%s, message=%s\n",
211 xmlBlasterException.errorCode, xmlBlasterException.message);
212 xa->disconnect(xa, 0, &xmlBlasterException);
213 freeXmlBlasterAccessUnparsed(xa);
214 exit(EXIT_FAILURE);
215 }
216 printf("[client] Publish success, returned status is '%s'\n", response);
217 xmlBlasterFree(response);
218 }
219
220 if (true) { /* publishArr */
221 QosArr* resp;
222 MsgUnitArr holder;
223 memset(&holder, 0, sizeof(MsgUnitArr));
224 printf("[client] Publishing messages 'HelloWorld0' and 'HelloWorld1' ...\n");
225 holder.len = 2;
226 holder.msgUnitArr = (MsgUnit *)calloc(holder.len, sizeof(MsgUnit));
227 holder.msgUnitArr[0].key = strcpyAlloc("<key oid='HelloWorld0'/>");
228 holder.msgUnitArr[0].content = strcpyAlloc("Some message payload");
229 holder.msgUnitArr[0].contentLen = strlen(holder.msgUnitArr[0].content);
230 holder.msgUnitArr[0].qos =strcpyAlloc("<qos><persistent/></qos>");
231
232 holder.msgUnitArr[1].key = strcpyAlloc("<key oid='HelloWorld1'/>");
233 holder.msgUnitArr[1].content = strcpyAlloc("Some message payload");
234 holder.msgUnitArr[1].contentLen = strlen(holder.msgUnitArr[1].content);
235 holder.msgUnitArr[1].qos =strcpyAlloc("<qos><persistent/></qos>");
236
237 resp = xa->publishArr(xa, &holder, &xmlBlasterException);
238
239 freeMsgUnitArrInternal(&holder);
240 if (*xmlBlasterException.errorCode != 0) {
241 printf("[client] Caught exception in publishArr errorCode=%s, message=%s\n",
242 xmlBlasterException.errorCode, xmlBlasterException.message);
243 xa->disconnect(xa, 0, &xmlBlasterException);
244 freeXmlBlasterAccessUnparsed(xa);
245 exit(EXIT_FAILURE);
246 }
247 if (resp) {
248 size_t i;
249 for (i=0; i<resp->len; i++) {
250 printf("[client] PublishArr success, returned status is '%s'\n", resp->qosArr[i]);
251 }
252 freeQosArr(resp);
253 }
254 }
255
256 if (true) { /* publishOneway */
257 MsgUnitArr holder;
258 memset(&holder, 0, sizeof(MsgUnitArr));
259 printf("[client] Publishing oneway messages 'HelloWorld0' and 'HelloWorld1' ...\n");
260 holder.len = 2;
261 holder.msgUnitArr = (MsgUnit *)calloc(holder.len, sizeof(MsgUnit));
262 holder.msgUnitArr[0].key = strcpyAlloc("<key oid='HelloWorld0'/>");
263 holder.msgUnitArr[0].content = strcpyAlloc("Some message payload");
264 holder.msgUnitArr[0].contentLen = strlen(holder.msgUnitArr[0].content);
265 holder.msgUnitArr[0].qos =strcpyAlloc("<qos><persistent/></qos>");
266
267 holder.msgUnitArr[1].key = strcpyAlloc("<key oid='HelloWorld1'/>");
268 holder.msgUnitArr[1].content = strcpyAlloc("Some message payload");
269 holder.msgUnitArr[1].contentLen = strlen(holder.msgUnitArr[1].content);
270 holder.msgUnitArr[1].qos =strcpyAlloc("<qos><persistent/></qos>");
271
272 xa->publishOneway(xa, &holder, &xmlBlasterException);
273
274 freeMsgUnitArrInternal(&holder);
275 if (*xmlBlasterException.errorCode != 0) {
276 printf("[client] Caught exception in publishOneway errorCode=%s, message=%s\n",
277 xmlBlasterException.errorCode, xmlBlasterException.message);
278 xa->disconnect(xa, 0, &xmlBlasterException);
279 freeXmlBlasterAccessUnparsed(xa);
280 exit(EXIT_FAILURE);
281 }
282 }
283
284 { /* unSubscribe ... */
285 QosArr* resp;
286 const char *key = "<key oid='HelloWorld'/>";
287 /*const char *key = "<key queryType='XPATH'>//key</key>";*/
288 const char *qos = "<qos/>";
289 printf("[client] UnSubscribe message 'HelloWorld' ...\n");
290 resp = xa->unSubscribe(xa, key, qos, &xmlBlasterException);
291 if (resp) {
292 size_t i;
293 for (i=0; i<resp->len; i++) {
294 printf("[client] Unsubscribe success, returned status is '%s'\n", resp->qosArr[i]);
295 }
296 freeQosArr(resp);
297 }
298 else {
299 printf("[client] Caught exception in unSubscribe errorCode=%s, message=%s\n",
300 xmlBlasterException.errorCode, xmlBlasterException.message);
301 xa->disconnect(xa, 0, &xmlBlasterException);
302 freeXmlBlasterAccessUnparsed(xa);
303 exit(EXIT_FAILURE);
304 }
305 }
306
307 { /* get synchronous ... */
308 size_t i;
309 /*const char *key = "<key oid='HelloWorld'/>";*/
310 const char *key = "<key queryType='XPATH'>//key</key>";
311 const char *qos = "<qos/>";
312 MsgUnitArr *msgUnitArr;
313 printf("[client] Get synchronous messages with XPath '//key' ...\n");
314 msgUnitArr = xa->get(xa, key, qos, &xmlBlasterException);
315 if (*xmlBlasterException.errorCode != 0) {
316 printf("[client] Caught exception in get errorCode=%s, message=%s\n",
317 xmlBlasterException.errorCode, xmlBlasterException.message);
318 xa->disconnect(xa, 0, &xmlBlasterException);
319 freeXmlBlasterAccessUnparsed(xa);
320 exit(EXIT_FAILURE);
321 }
322 if (msgUnitArr != (MsgUnitArr *)0) {
323 for (i=0; i<msgUnitArr->len; i++) {
324 char *m = messageUnitToXmlLimited(&msgUnitArr->msgUnitArr[i], 100);
325 printf("\n[client] Get synchronous returned message#%lu/%lu:\n"
326 "-------------------------------------"
327 "%s\n"
328 "-------------------------------------\n",
329 (unsigned long)(i+1), (unsigned long)msgUnitArr->len, m);
330 xmlBlasterFree(m);
331 }
332 freeMsgUnitArr(msgUnitArr);
333 }
334 else {
335 printf("[client] Caught exception in get errorCode=%s, message=%s\n",
336 xmlBlasterException.errorCode, xmlBlasterException.message);
337 xa->disconnect(xa, 0, &xmlBlasterException);
338 freeXmlBlasterAccessUnparsed(xa);
339 exit(EXIT_FAILURE);
340 }
341 }
342
343
344 { /* erase ... */
345 QosArr* resp;
346 const char *key = "<key oid='HelloWorld'/>";
347 /*const char *key = "<key oid='' queryType='XPATH'>//key</key>";*/
348 const char *qos = "<qos/>";
349 printf("[client] Erasing message 'HelloWorld' ...\n");
350 resp = xa->erase(xa, key, qos, &xmlBlasterException);
351 if (*xmlBlasterException.errorCode != 0) {
352 printf("[client] Caught exception in erase errorCode=%s, message=%s\n",
353 xmlBlasterException.errorCode, xmlBlasterException.message);
354 xa->disconnect(xa, 0, &xmlBlasterException);
355 freeXmlBlasterAccessUnparsed(xa);
356 exit(EXIT_FAILURE);
357 }
358 if (resp != 0) {
359 size_t i;
360 for (i=0; i<resp->len; i++) {
361 printf("[client] Erase success, returned status is '%s'\n", resp->qosArr[i]);
362 }
363 freeQosArr(resp);
364 }
365 }
366
367 sleepMillis(200); /* To allow the callback thread to publish */
368
369 if (xa->disconnect(xa, 0, &xmlBlasterException) == false) {
370 printf("[client] Caught exception in disconnect, errorCode=%s, message=%s\n",
371 xmlBlasterException.errorCode, xmlBlasterException.message);
372 freeXmlBlasterAccessUnparsed(xa);
373 exit(EXIT_FAILURE);
374 }
375
376 freeXmlBlasterAccessUnparsed(xa);
377 printf("[client] Good bye.\n");
378 # if defined(WINCE)
379 freeArgv(argv, argc);
380 # endif
381 return 0;
382 }
syntax highlighted by Code2HTML, v. 0.9.1