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