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