demo/c/socket/HelloWorld3.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002 Name:      xmlBlaster/demo/c/socket/HelloWorld3.c
00003 Project:   xmlBlaster.org
00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
00005 Comment:   Example for all remote method invocations.
00006 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
00007 Compile:   cd xmlBlaster; build c
00008            (Win: copy xmlBlaster\src\c\socket\pthreadVC2.dll to your PATH)
00009            Manually:
00010             cd xmlBlaster/src/c
00011             gcc -g -Wall -pedantic -Wno-long-long -D_REENTRANT -I. -o HelloWorld3 
00012                 ../../demo/c/socket/HelloWorld3.c util/?*.c socket/?*.c -pthread
00013 Invoke:    HelloWorld3 -help
00014 See: http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html
00015 -----------------------------------------------------------------------------*/
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <XmlBlasterAccessUnparsed.h>
00020 
00029 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
00030                      XmlBlasterException *exception)
00031 {
00032    size_t i;
00033    bool testException = false;
00034    XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData;
00035 
00036    for (i=0; i<msgUnitArr->len; i++) {
00037       char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
00038       printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
00039              xml);
00040       xmlBlasterFree(xml);
00041       msgUnitArr->msgUnitArr[i].responseQos = 
00042                   strcpyAlloc("<qos><state id='OK'/></qos>");
00043       /* Return QoS: Everything is OK */
00044    }
00045    if (testException) {
00046       strncpy0(exception->errorCode, "user.clientCode",
00047                XMLBLASTEREXCEPTION_ERRORCODE_LEN);
00048       strncpy0(exception->message, "I don't want these messages",
00049                XMLBLASTEREXCEPTION_MESSAGE_LEN);
00050       return false;
00051    }
00052 
00053    if (xa->callbackMultiThreaded == true) {
00054       /* publish from inside the update thread,
00055          see -plugin/socket/multiThreaded true */
00056       char *response = (char *)0;
00057       MsgUnit msgUnit;
00058       XmlBlasterException xmlBlasterException;
00059       memset(&msgUnit, 0, sizeof(MsgUnit));
00060       printf("[client] Publishing message 'HelloWorldCb from update thread' ...\n");
00061       msgUnit.key = strcpyAlloc("<key oid='HelloWorldCb'/>");
00062       msgUnit.content = strcpyAlloc("Some message payload");
00063       msgUnit.contentLen = strlen(msgUnit.content);
00064       msgUnit.qos =strcpyAlloc("<qos><persistent/></qos>");
00065       response = xa->publish(xa, &msgUnit, &xmlBlasterException);
00066       freeMsgUnitData(&msgUnit);
00067       if (*xmlBlasterException.errorCode != 0) {
00068          printf("[client] Caught exception in publish errorCode=%s, message=%s\n",
00069                   xmlBlasterException.errorCode, xmlBlasterException.message);
00070          xa->disconnect(xa, 0, &xmlBlasterException);
00071          freeXmlBlasterAccessUnparsed(xa);
00072          exit(EXIT_FAILURE);
00073       }
00074       printf("[client] Publish success, returned status is '%s'\n", response);
00075       xmlBlasterFree(response);
00076    }
00077  
00078    return true;
00079 }
00080 
00081 #if defined(WINCE)
00082 int _tmain(int argc, _TCHAR** argv_wcs) { /* wchar_t==_TCHAR */
00083    char **argv = convertWcsArgv(argv_wcs, argc);
00084 #else
00085 
00088 int main(int argc, const char* const* argv) {
00089 #endif
00090    int iarg;
00091    char *response = (char *)0;
00092    /*
00093       * callbackSessionId:
00094       * Is created by the client and used to validate callback messages in update. 
00095       * This is sent on connect in ConnectQos.
00096       * (Is different from the xmlBlaster secret session ID)
00097       */
00098    const char *callbackSessionId = "topSecret";
00099    XmlBlasterException xmlBlasterException;
00100    XmlBlasterAccessUnparsed *xa = 0;
00101    int sleepInterval = 0;
00102 
00103    printf("[client] XmlBlaster %s C SOCKET client, try option '-help' if you need"
00104           " usage informations\n", getXmlBlasterVersion());
00105 
00106    for (iarg=0; iarg < argc; iarg++) {
00107       if (strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "--help") == 0) {
00108          char usage[XMLBLASTER_MAX_USAGE_LEN];
00109          const char *pp =
00110          "\n   -sleepInterval      Milliseconds to wait on callback messages [0]"
00111          "\n\nExample:"
00112          "\n  HelloWorld3 -logLevel TRACE"
00113          " -dispatch/connection/plugin/socket/hostname 192.168.2.9"
00114          " -sleepInterval 100000";
00115          printf("Usage:\nXmlBlaster C SOCKET client %s\n%s%s\n",
00116                   getXmlBlasterVersion(), xmlBlasterAccessUnparsedUsage(usage), pp);
00117          exit(EXIT_FAILURE);
00118       }
00119       else if (strcmp(argv[iarg], "-sleepInterval") == 0 && iarg < argc-1)
00120          sleepInterval = atoi(argv[++iarg]);
00121    }
00122 
00123    xa = getXmlBlasterAccessUnparsed(argc, (const char* const*)argv);
00124    if (xa->initialize(xa, myUpdate, &xmlBlasterException) == false) {
00125       printf("[client] Connection to xmlBlaster failed,"
00126              " please start the server or check your configuration:\n%s %s\n",
00127              xmlBlasterException.errorCode, xmlBlasterException.message);
00128       freeXmlBlasterAccessUnparsed(xa);
00129       exit(EXIT_FAILURE);
00130    }
00131 
00132    {  /* connect */
00133       char connectQos[2048];
00134       char callbackQos[1024];
00135       sprintf(callbackQos,
00136                "<queue relating='callback' maxEntries='50000' maxEntriesCache='10000'>"
00137                "  <callback type='SOCKET' sessionId='%.120s'>"
00138                "    socket://%.120s:%d"
00139                "  </callback>"
00140                "</queue>",
00141                callbackSessionId, xa->callbackP->hostCB, xa->callbackP->portCB);
00142       sprintf(connectQos,
00143                "<qos>"
00144                " <securityService type='htpasswd' version='1.0'>"
00145                "  <![CDATA["
00146                "   <user>fritz</user>"
00147                "   <passwd>secret</passwd>"
00148                "  ]]>"
00149                " </securityService>"
00150                "  <session name='client/fritz' timeout='0' maxSessions='1'/>"
00151                "%.1024s"
00152                "</qos>", callbackQos);
00153 
00154       response = xa->connect(xa, connectQos, myUpdate, &xmlBlasterException);
00155       if (*xmlBlasterException.errorCode != 0) {
00156          printf("[client] Caught exception during connect errorCode=%s, message=%s\n",
00157                   xmlBlasterException.errorCode, xmlBlasterException.message);
00158          freeXmlBlasterAccessUnparsed(xa);
00159          exit(EXIT_FAILURE);
00160       }
00161       xmlBlasterFree(response);
00162       printf("[client] Connected to xmlBlaster, do some tests ...\n");
00163    }
00164 
00165    response = xa->ping(xa, 0, &xmlBlasterException);
00166    if (response == (char *)0) {
00167       printf("[client] ERROR: Pinging a connected server failed: errorCode=%s, message=%s\n",
00168              xmlBlasterException.errorCode, xmlBlasterException.message);
00169       freeXmlBlasterAccessUnparsed(xa);
00170       exit(EXIT_FAILURE);
00171    }
00172    else {
00173       printf("[client] Pinging a connected server, response=%s\n", response);
00174       xmlBlasterFree(response);
00175    }
00176 
00177    { /* subscribe ... */
00178       const char *key = "<key oid='HelloWorld'/>";
00179       /*const char *key = "<key queryType='XPATH'>//key</key>";*/
00180       const char *qos = "<qos/>";
00181       printf("[client] Subscribe message 'HelloWorld' ...\n");
00182       response = xa->subscribe(xa, key, qos, &xmlBlasterException);
00183       if (*xmlBlasterException.errorCode != 0) {
00184          printf("[client] Caught exception in subscribe errorCode=%s, message=%s\n",
00185                   xmlBlasterException.errorCode, xmlBlasterException.message);
00186          xa->disconnect(xa, 0, &xmlBlasterException);
00187          freeXmlBlasterAccessUnparsed(xa);
00188          exit(EXIT_FAILURE);
00189       }
00190       printf("[client] Subscribe success, returned status is '%s'\n", response);
00191       xmlBlasterFree(response);
00192    }
00193    
00194    if (sleepInterval > 0) {
00195       printf("[client] Sleeping now and wait on 'HelloWorld' updates (start a publisher somewhere) ...\n");
00196       sleepMillis(sleepInterval);
00197    }
00198 
00199    {  /* publish ... */
00200       MsgUnit msgUnit;
00201       memset(&msgUnit, 0, sizeof(MsgUnit));
00202       printf("[client] Publishing message 'HelloWorld' ...\n");
00203       msgUnit.key = strcpyAlloc("<key oid='HelloWorld'/>");
00204       msgUnit.content = strcpyAlloc("Some message payload");
00205       msgUnit.contentLen = strlen(msgUnit.content);
00206       msgUnit.qos =strcpyAlloc("<qos><persistent/></qos>");
00207       response = xa->publish(xa, &msgUnit, &xmlBlasterException);
00208       freeMsgUnitData(&msgUnit);
00209       if (*xmlBlasterException.errorCode != 0) {
00210          printf("[client] Caught exception in publish errorCode=%s, message=%s\n",
00211                   xmlBlasterException.errorCode, xmlBlasterException.message);
00212          xa->disconnect(xa, 0, &xmlBlasterException);
00213          freeXmlBlasterAccessUnparsed(xa);
00214          exit(EXIT_FAILURE);
00215       }
00216       printf("[client] Publish success, returned status is '%s'\n", response);
00217       xmlBlasterFree(response);
00218    }
00219  
00220    if (true) {  /* publishArr */
00221       QosArr* resp;
00222       MsgUnitArr holder;
00223       memset(&holder, 0, sizeof(MsgUnitArr));
00224       printf("[client] Publishing messages 'HelloWorld0' and 'HelloWorld1' ...\n");
00225       holder.len = 2;
00226       holder.msgUnitArr = (MsgUnit *)calloc(holder.len, sizeof(MsgUnit));
00227       holder.msgUnitArr[0].key = strcpyAlloc("<key oid='HelloWorld0'/>");
00228       holder.msgUnitArr[0].content = strcpyAlloc("Some message payload");
00229       holder.msgUnitArr[0].contentLen = strlen(holder.msgUnitArr[0].content);
00230       holder.msgUnitArr[0].qos =strcpyAlloc("<qos><persistent/></qos>");
00231 
00232       holder.msgUnitArr[1].key = strcpyAlloc("<key oid='HelloWorld1'/>");
00233       holder.msgUnitArr[1].content = strcpyAlloc("Some message payload");
00234       holder.msgUnitArr[1].contentLen = strlen(holder.msgUnitArr[1].content);
00235       holder.msgUnitArr[1].qos =strcpyAlloc("<qos><persistent/></qos>");
00236 
00237       resp = xa->publishArr(xa, &holder, &xmlBlasterException);
00238       
00239       freeMsgUnitArrInternal(&holder);
00240       if (*xmlBlasterException.errorCode != 0) {
00241          printf("[client] Caught exception in publishArr errorCode=%s, message=%s\n",
00242                   xmlBlasterException.errorCode, xmlBlasterException.message);
00243          xa->disconnect(xa, 0, &xmlBlasterException);
00244          freeXmlBlasterAccessUnparsed(xa);
00245          exit(EXIT_FAILURE);
00246       }
00247       if (resp) {
00248          size_t i;
00249          for (i=0; i<resp->len; i++) {
00250             printf("[client] PublishArr success, returned status is '%s'\n", resp->qosArr[i]);
00251          }
00252          freeQosArr(resp);
00253       }
00254    }
00255  
00256    if (true) {  /* publishOneway */
00257       MsgUnitArr holder;
00258       memset(&holder, 0, sizeof(MsgUnitArr));
00259       printf("[client] Publishing oneway messages 'HelloWorld0' and 'HelloWorld1' ...\n");
00260       holder.len = 2;
00261       holder.msgUnitArr = (MsgUnit *)calloc(holder.len, sizeof(MsgUnit));
00262       holder.msgUnitArr[0].key = strcpyAlloc("<key oid='HelloWorld0'/>");
00263       holder.msgUnitArr[0].content = strcpyAlloc("Some message payload");
00264       holder.msgUnitArr[0].contentLen = strlen(holder.msgUnitArr[0].content);
00265       holder.msgUnitArr[0].qos =strcpyAlloc("<qos><persistent/></qos>");
00266 
00267       holder.msgUnitArr[1].key = strcpyAlloc("<key oid='HelloWorld1'/>");
00268       holder.msgUnitArr[1].content = strcpyAlloc("Some message payload");
00269       holder.msgUnitArr[1].contentLen = strlen(holder.msgUnitArr[1].content);
00270       holder.msgUnitArr[1].qos =strcpyAlloc("<qos><persistent/></qos>");
00271 
00272       xa->publishOneway(xa, &holder, &xmlBlasterException);
00273       
00274       freeMsgUnitArrInternal(&holder);
00275       if (*xmlBlasterException.errorCode != 0) {
00276          printf("[client] Caught exception in publishOneway errorCode=%s, message=%s\n",
00277                   xmlBlasterException.errorCode, xmlBlasterException.message);
00278          xa->disconnect(xa, 0, &xmlBlasterException);
00279          freeXmlBlasterAccessUnparsed(xa);
00280          exit(EXIT_FAILURE);
00281       }
00282    }
00283  
00284    {  /* unSubscribe ... */
00285       QosArr* resp;
00286       const char *key = "<key oid='HelloWorld'/>";
00287       /*const char *key = "<key queryType='XPATH'>//key</key>";*/
00288       const char *qos = "<qos/>";
00289       printf("[client] UnSubscribe message 'HelloWorld' ...\n");
00290       resp = xa->unSubscribe(xa, key, qos, &xmlBlasterException);
00291       if (resp) {
00292          size_t i;
00293          for (i=0; i<resp->len; i++) {
00294             printf("[client] Unsubscribe success, returned status is '%s'\n", resp->qosArr[i]);
00295          }
00296          freeQosArr(resp);
00297       }
00298       else {
00299          printf("[client] Caught exception in unSubscribe errorCode=%s, message=%s\n",
00300                   xmlBlasterException.errorCode, xmlBlasterException.message);
00301          xa->disconnect(xa, 0, &xmlBlasterException);
00302          freeXmlBlasterAccessUnparsed(xa);
00303          exit(EXIT_FAILURE);
00304       }
00305    }
00306 
00307    {  /* get synchronous ... */
00308       size_t i;
00309       /*const char *key = "<key oid='HelloWorld'/>";*/
00310       const char *key = "<key queryType='XPATH'>//key</key>";
00311       const char *qos = "<qos/>";
00312       MsgUnitArr *msgUnitArr;
00313       printf("[client] Get synchronous messages with XPath '//key' ...\n");
00314       msgUnitArr = xa->get(xa, key, qos, &xmlBlasterException);
00315       if (*xmlBlasterException.errorCode != 0) {
00316          printf("[client] Caught exception in get errorCode=%s, message=%s\n",
00317                   xmlBlasterException.errorCode, xmlBlasterException.message);
00318          xa->disconnect(xa, 0, &xmlBlasterException);
00319          freeXmlBlasterAccessUnparsed(xa);
00320          exit(EXIT_FAILURE);
00321       }
00322       if (msgUnitArr != (MsgUnitArr *)0) {
00323          for (i=0; i<msgUnitArr->len; i++) {
00324             char *m = messageUnitToXmlLimited(&msgUnitArr->msgUnitArr[i], 100);
00325             printf("\n[client] Get synchronous returned message#%lu/%lu:\n"
00326                      "-------------------------------------"
00327                      "%s\n"
00328                      "-------------------------------------\n",
00329                      (unsigned long)(i+1), (unsigned long)msgUnitArr->len, m);
00330             xmlBlasterFree(m);
00331          }
00332          freeMsgUnitArr(msgUnitArr);
00333       }
00334       else {
00335          printf("[client] Caught exception in get errorCode=%s, message=%s\n",
00336                   xmlBlasterException.errorCode, xmlBlasterException.message);
00337          xa->disconnect(xa, 0, &xmlBlasterException);
00338          freeXmlBlasterAccessUnparsed(xa);
00339          exit(EXIT_FAILURE);
00340       }
00341    }
00342 
00343 
00344    {  /* erase ... */
00345       QosArr* resp;
00346       const char *key = "<key oid='HelloWorld'/>";
00347       /*const char *key = "<key oid='' queryType='XPATH'>//key</key>";*/
00348       const char *qos = "<qos/>";
00349       printf("[client] Erasing message 'HelloWorld' ...\n");
00350       resp = xa->erase(xa, key, qos, &xmlBlasterException);
00351       if (*xmlBlasterException.errorCode != 0) {
00352          printf("[client] Caught exception in erase errorCode=%s, message=%s\n",
00353                   xmlBlasterException.errorCode, xmlBlasterException.message);
00354          xa->disconnect(xa, 0, &xmlBlasterException);
00355          freeXmlBlasterAccessUnparsed(xa);
00356          exit(EXIT_FAILURE);
00357       }
00358       if (resp != 0) {
00359          size_t i;
00360          for (i=0; i<resp->len; i++) {
00361             printf("[client] Erase success, returned status is '%s'\n", resp->qosArr[i]);
00362          }
00363          freeQosArr(resp);
00364       }
00365    }
00366 
00367    sleepMillis(200); /* To allow the callback thread to publish */
00368 
00369    if (xa->disconnect(xa, 0, &xmlBlasterException) == false) {
00370       printf("[client] Caught exception in disconnect, errorCode=%s, message=%s\n",
00371                xmlBlasterException.errorCode, xmlBlasterException.message);
00372       freeXmlBlasterAccessUnparsed(xa);
00373       exit(EXIT_FAILURE);
00374    }
00375 
00376    freeXmlBlasterAccessUnparsed(xa);
00377    printf("[client] Good bye.\n");
00378 #  if defined(WINCE)
00379       freeArgv(argv, argc);
00380 #  endif
00381    return 0;
00382 }
00383