//采用单播形式发送probe,发送会马上阻塞等待一个事件响应,事件参考event.c //只能接收一个event,用于指定地址probe,比如手动添加IPC static int probeUnicast(const char *endpoint, const char * types, const char *scopes,int timeout) { struct soap *soap = soap_new1(SOAP_IO_UDP); // to invoke messages int ret; const char *id = soap_wsa_rand_uuid(soap); //设置超时时间,>0单位为秒 =0 用不超时 <0单位为微秒 soap->accept_timeout = soap->recv_timeout = soap->send_timeout = timeout; ret = soap_wsdd_Probe(soap, SOAP_WSDD_MANAGED,//SOAP_WSDD_ADHOC, // ad-hoc mode SOAP_WSDD_TO_TS, // to a TS endpoint, // address of TS; "soap.udp://239.255.255.250:3702" id, // message ID NULL, // ReplyTo,表示回应的message ID,因为是主动回发起,所以没有,填NULL types, //types,搜寻的设备类型"dn:NetworkVideoTransmitter tds:Device" scopes, //scopes,指定搜索范围,无填 NULL NULL); //match by,匹配规则,无填 NULL if(ret!=SOAP_OK) { soap_print_fault(soap, stderr); printf("soap_wsdd_Probe error,ret=%d\n",ret); } soap_end(soap); soap_free(soap); return ret; }
soap_wsdd_mode wsdd_event_Probe(struct soap *soap, const char *MessageID, const char *ReplyTo, const char *Types, const char *Scopes, const char *MatchBy, struct wsdd__ProbeMatchesType *matches) { printf("wsdd_event_Probe id=%s replyTo=%s types=%s scopes=%s\n", MessageID, ReplyTo, Types, Scopes); soap_wsdd_init_ProbeMatches(soap,matches); soap_wsdd_add_ProbeMatch(soap, matches, "soap.udp://239.255.255.250:3702", _type, NULL, NULL, _xaddr, _metadataVersion); soap_wsdd_ProbeMatches(soap, "soap.udp://239.255.255.250:3702", soap_wsa_rand_uuid(soap) , MessageID, ReplyTo, matches); return SOAP_WSDD_ADHOC; }
int Service::DivideBy(_mssadh__DivideBy *req) { /* check for WS-RM/WSA */ if (soap_wsrm_check(soap)) return soap->error; if (req && req->n) { result /= *req->n; equation << " / " << *req->n; } else return soap_wsrm_sender_fault(soap, "Invalid data in DivideBy", NULL); /* this is a one-way operation over HTTP, so we're done with client */ soap_send_empty_response(soap, 202); /* get the handle to the current sequence of the inbound message */ soap_wsrm_sequence_handle seq = soap_wsrm_seq(soap); /* TODO: send acknowledgement(s) immediately? */ /* soap_wsrm_acknowledgement(soap, seq, NULL); */ if (soap_wsrm_request_acks(callback.soap, seq, soap_wsa_rand_uuid(callback.soap), "http://Microsoft.Samples.DualHttp/ICalculatorDuplex/Result")) { callback.soap_stream_fault(std::cerr); soap_wsrm_seq_release(soap, seq); return callback.soap->error; } callback.soap_endpoint = soap_wsrm_to(seq); soap_wsrm_seq_release(soap, seq); if (callback.soap_endpoint) { _mssadh__Result res; res.result = &result; if (callback.send_Result(&res) == SOAP_OK) std::cout << "Result(" << result << ")" << std::endl; else callback.soap_stream_fault(std::cerr); } callback.destroy(); return SOAP_OK; }
//采用多播形式发送probe,立即返回不阻塞等待事件响应,获取事件响应要主动接下对应的sock或调用soap_wsdd_listen函数,事件参考event.c //可以接收多个event,用于探测网络中存在的IPC static int probeMulticast(const char *endpoint, const char * types, const char *scopes,int timeout) { struct soap *serv = soap_new1(SOAP_IO_UDP); // to invoke messages int ret; const char *id = soap_wsa_rand_uuid(serv); ret = soap_wsdd_Probe(serv, SOAP_WSDD_ADHOC,//SOAP_WSDD_ADHOC, // ad-hoc mode SOAP_WSDD_TO_TS, // to a TS endpoint, // address of TS; "soap.udp://239.255.255.250:3702" id, // message ID NULL, // ReplyTo,表示回应的message ID,因为是主动回发起,所以没有,填NULL types, //types,搜寻的设备类型"dn:NetworkVideoTransmitter tds:Device" scopes, //scopes,指定搜索范围,无填 NULL NULL); //match by,匹配规则,无填 NULL if(ret!=SOAP_OK) { soap_print_fault(serv, stderr); printf("soap_wsdd_Probe error,ret=%d\n",ret); goto ERR0; } if (!soap_valid_socket(serv->socket)) { soap_print_fault(serv, stderr); printf("sock is error\n"); ret = -1; goto ERR0; } serv->master = serv->socket;//必须指定,否则无法监听 ret = soap_wsdd_listen(serv,timeout); if(ret!=SOAP_OK) { soap_print_fault(serv, stderr); printf("soap_wsdd_listen error,ret=%d\n",ret); goto ERR0; } ERR0: soap_end(serv); soap_free(serv); return ret; }
void sendBye() { struct soap* soap = soap_new1(SOAP_IO_UDP); printf("call soap_wsdd_Bye\n"); int res = soap_wsdd_Bye(soap, SOAP_WSDD_ADHOC, // mode "soap.udp://239.255.255.250:3702", // address of TS soap_wsa_rand_uuid(soap), // message ID _endpoint, NULL, _type, NULL, _xaddr, _metadataVersion); if (res != SOAP_OK) { soap_print_fault(soap, stderr); } soap_end(soap); }
int Service::Clear(_mssadh__Clear *req) { /* check for WS-RM/WSA, send empty response (this is a one-way operation over HTTP) */ if (soap_wsrm_check_send_empty_response(soap)) return soap->error; /* get the handle to the current sequence of the inbound message */ soap_wsrm_sequence_handle seq = soap_wsrm_seq(soap); /* TODO: send acknowledgement(s) immediately? */ /* soap_wsrm_acknowledgement(soap, seq, NULL); */ if (soap_wsrm_request_acks(callback.soap, seq, soap_wsa_rand_uuid(callback.soap), "http://Microsoft.Samples.DualHttp/ICalculatorDuplex/Equation")) { callback.soap_stream_fault(std::cerr); soap_wsrm_seq_release(soap, seq); return callback.soap->error; } callback.soap_endpoint = soap_wsrm_to(seq); soap_wsrm_seq_release(soap, seq); equation << " = " << result; if (callback.soap_endpoint) { _mssadh__Equation eqn; std::string s = equation.str(); eqn.eqn = &s; if (callback.Equation(&eqn) == SOAP_OK) std::cout << "Equation(" << s << ")" << std::endl; else callback.soap_stream_fault(std::cerr); } callback.destroy(); result = 0.0; equation.str(""); equation << 0.0; return SOAP_OK; }
int Client::run() { // Create a reliable messaging sequence handle for client-initiated session soap_wsrm_sequence_handle seq; xsd__duration expires = 30000; /* 30000 ms = 30 seconds to expire */ const char *id = soap_wsa_rand_uuid(soap); double n; int retry; printf("\n**** Creating the Sequence\n"); // Create session for in-order messaging, init sequence handle if (soap_wsrm_create_offer(soap, serverURI, clientURI, id, expires, NoDiscard, soap_wsa_rand_uuid(soap), &seq)) { soap_stream_fault(std::cerr); soap_wsrm_seq_free(soap, seq); return soap->error; } // poll 100 times for .1 second until created for (retry = 100; retry && !soap_wsrm_seq_created(soap, seq); retry--) { if (poll(-100000)) return soap->error; } if (!retry) { fprintf(stderr, "CANNOT CREATE SEQUENCE - SERVER NOT RESPONDING\n"); exit(1); } // Reliable messaging request message if (soap_wsrm_request_acks(soap, seq, soap_wsa_rand_uuid(soap), "http://Microsoft.Samples.DualHttp/ICalculatorDuplex/AddTo")) { soap_stream_fault(std::cerr); return soap->error; } n = 3.14; _mssadh__AddTo addTo; addTo.n = &n; if (AddTo(&addTo) == SOAP_OK) std::cout << std::endl << "**** AddTo(" << *addTo.n << ")" << std::endl; else soap_stream_fault(std::cerr); destroy(); #ifndef CB_THREAD // callback polling: 500 ms polling cycle if (poll(-500000)) return soap->error; #endif // Reliable messaging request message if (soap_wsrm_request_acks(soap, seq, soap_wsa_rand_uuid(soap), "http://Microsoft.Samples.DualHttp/ICalculatorDuplex/SubtractFrom")) { soap_stream_fault(std::cerr); return soap->error; } n = 1.41; _mssadh__SubtractFrom subtractFrom; subtractFrom.n = &n; if (SubtractFrom(&subtractFrom) == SOAP_OK) std::cout << std::endl << "**** SubtractFrom(" << *subtractFrom.n << ")" << std::endl; else soap_stream_fault(std::cerr); destroy(); #ifndef CB_THREAD // callback polling: 500 ms polling cycle if (poll(-500000)) return soap->error; #endif // Reliable messaging request message if (soap_wsrm_request_acks(soap, seq, soap_wsa_rand_uuid(soap), "http://Microsoft.Samples.DualHttp/ICalculatorDuplex/Clear")) { soap_stream_fault(std::cerr); return soap->error; } _mssadh__Clear clear; if (Clear(&clear) == SOAP_OK) std::cout << std::endl << "**** Clear()" << std::endl; else soap_stream_fault(std::cerr); destroy(); #ifndef CB_THREAD // callback polling: 500 ms polling cycle if (poll(-500000)) return soap->error; #endif printf("\n**** Closing the Sequence\n"); if (soap_wsrm_close(soap, seq, soap_wsa_rand_uuid(soap))) { soap_stream_fault(std::cerr); soap_wsrm_seq_free(soap, seq); return soap->error; } for (retry = 10; retry; retry--) { // Receive more messages when last not yet received if (soap_wsrm_lastnum(seq) == 0) { #ifdef CB_THREAD // we want to pulse here to send acks for incoming messages to keep flow going soap_wsrm_pulse(soap, -500000); /* 500 ms */ #endif printf("\n**** Receiving Messages Until Last\n"); // callback polling or delay: 500 ms polling cycle if (poll(-500000)) return soap->error; } // Resend messages marked as non-acked (as an option) if (soap_wsrm_nack(seq)) { printf("\n**** Resending "SOAP_ULONG_FORMAT" Non-Acked Messages\n", soap_wsrm_nack(seq)); soap_wsrm_resend(soap, seq, 0, 0); /* 0 0 means full range of msg nums */ } } if (soap_wsrm_nack(seq) || soap_wsrm_lastnum(seq) == 0) { printf("\n**** Incomplete Sequence\n"); soap_wsrm_dump(soap, stdout); } printf("\n**** Terminating the Sequence\n"); // Termination fails if the server did not get all messages if (soap_wsrm_terminate(soap, seq, soap_wsa_rand_uuid(soap))) { soap_stream_fault(std::cerr); soap_wsrm_seq_free(soap, seq); return soap->error; } #ifdef CB_THREAD soap_wsrm_dump(soap, stdout); #endif // callback polling: 1 s polling cycle if (poll(1)) return soap->error; // Delete the reliable messaging session sequence (assuming no more inbound messages) soap_wsrm_seq_free(soap, seq); return 0; }