Commit a4413814b3db670d5c26d8cb2273b1781f39793e
1 parent
471d55f3
A bug appeared during python library bindings, or so it seems.
Showing
3 changed files
with
191 additions
and
39 deletions
include/GVOHub.hpp
| ... | ... | @@ -74,10 +74,11 @@ protected: |
| 74 | 74 | void start_hub(void); |
| 75 | 75 | //bool find_hub(void); |
| 76 | 76 | //void connect_to_hub(void); |
| 77 | - void register_service(const socklen_t& sock); | |
| 78 | - void unregister(void); | |
| 77 | + void register_service(const GXml& xml,const socklen_t& sock); | |
| 78 | + void ping_service(const socklen_t& sock); | |
| 79 | + void unregister(const socklen_t& sock); | |
| 79 | 80 | void handle_request(const socklen_t& sock); |
| 80 | - void register_metadata(const GXml& xml); | |
| 81 | + void register_metadata(const GXml& xml,const socklen_t& sock); | |
| 81 | 82 | |
| 82 | 83 | // Low-level methods |
| 83 | 84 | void post_string(const std::string& string) const; |
| ... | ... | @@ -97,6 +98,12 @@ protected: |
| 97 | 98 | std::string m_hub_id; //!< Hub identifier |
| 98 | 99 | std::string m_client_id; //!< Client identifier |
| 99 | 100 | int m_socket; //!< Hub socket |
| 101 | + int m_nb_clients; //!< Number of already registered clients | |
| 102 | + struct client_metadata { | |
| 103 | + std::string client_id; | |
| 104 | + std::string client_name; | |
| 105 | + }; | |
| 106 | + static client_metadata * Clients; //Array of structure containing clients id and names | |
| 100 | 107 | }; |
| 101 | 108 | |
| 102 | 109 | #endif /* GVOHUB_HPP */ | ... | ... |
src/vo/GVOClient.cpp
| ... | ... | @@ -174,11 +174,15 @@ GVOClient* GVOClient::clone(void) const |
| 174 | 174 | void GVOClient::connect(void) |
| 175 | 175 | { |
| 176 | 176 | // Register to Hub |
| 177 | + printf("Sending registration to hub\n"); | |
| 178 | + fflush(stdout); | |
| 177 | 179 | register_to_hub(); |
| 178 | - | |
| 180 | + printf("Registration to hub sent\n"); | |
| 181 | + fflush(stdout); | |
| 179 | 182 | // Send meta data |
| 180 | 183 | send_metadata(); |
| 181 | - | |
| 184 | + printf("Metadata sent\n"); | |
| 185 | + fflush(stdout); | |
| 182 | 186 | // Return |
| 183 | 187 | return; |
| 184 | 188 | } |
| ... | ... | @@ -246,7 +250,8 @@ GXml GVOClient::response(void) const |
| 246 | 250 | |
| 247 | 251 | // Continue only if connection has been established |
| 248 | 252 | if (m_socket != -1) { |
| 249 | - | |
| 253 | + printf("Socket identified, receive string\n"); | |
| 254 | + fflush(stdout); | |
| 250 | 255 | // Receive a string |
| 251 | 256 | std::string response = receive_string(); |
| 252 | 257 | |
| ... | ... | @@ -261,6 +266,8 @@ GXml GVOClient::response(void) const |
| 261 | 266 | } // endif: connection has been established |
| 262 | 267 | |
| 263 | 268 | // Return XML document |
| 269 | + printf("End of response function\n"); | |
| 270 | + fflush(stdout); | |
| 264 | 271 | return xml; |
| 265 | 272 | } |
| 266 | 273 | |
| ... | ... | @@ -599,10 +606,14 @@ void GVOClient::register_to_hub(void) |
| 599 | 606 | |
| 600 | 607 | // Post message |
| 601 | 608 | post_string(msg); |
| 602 | - | |
| 609 | + printf("Waiting for Hub response\n"); | |
| 610 | + fflush(stdout); | |
| 603 | 611 | // Get Hub response |
| 604 | 612 | GXml xml = response(); |
| 605 | 613 | |
| 614 | + printf("Hub response received"); | |
| 615 | + fflush(stdout); | |
| 616 | + | |
| 606 | 617 | // Extract Hub and client identifiers |
| 607 | 618 | m_client_key = get_response_value(xml, "samp.private-key"); |
| 608 | 619 | m_hub_id = get_response_value(xml, "samp.hub-id"); |
| ... | ... | @@ -666,6 +677,8 @@ void GVOClient::send_metadata(void) |
| 666 | 677 | // Maybe this is socket standard? |
| 667 | 678 | connect_to_hub(); |
| 668 | 679 | |
| 680 | + printf("send metadata function \n"); | |
| 681 | + fflush(stdout); | |
| 669 | 682 | // Continue only if Hub connection has been established |
| 670 | 683 | if (m_socket != -1) { |
| 671 | 684 | |
| ... | ... | @@ -847,7 +860,7 @@ void GVOClient::post_string(const std::string& content) const |
| 847 | 860 | int length = content.length(); |
| 848 | 861 | |
| 849 | 862 | // Set prefix |
| 850 | - std::string prefix = "POST /xmlrpc HTTP/1.0\n" | |
| 863 | + std::string prefix = "POST /xmlrpc-1 HTTP/1.0\n" | |
| 851 | 864 | "User-Agent: GammaLib\n" |
| 852 | 865 | "Content-Type: text/xml\n" |
| 853 | 866 | "Content-Length: "+gammalib::str(length)+"\n\n"; |
| ... | ... | @@ -897,13 +910,17 @@ std::string GVOClient::receive_string(void) const |
| 897 | 910 | |
| 898 | 911 | // Read buffer until it is empty |
| 899 | 912 | int n = 0; |
| 900 | - do { | |
| 913 | + //do { | |
| 914 | + printf("receive socket instruction\n"); | |
| 915 | + fflush(stdout); | |
| 901 | 916 | n = recv(m_socket, buffer, 1000, 0); |
| 917 | + printf("data received: %s\n",buffer); | |
| 918 | + fflush(stdout); | |
| 902 | 919 | if (n > 0) { |
| 903 | 920 | buffer[n+1] = '\0'; |
| 904 | 921 | result.append(std::string(buffer)); |
| 905 | 922 | } |
| 906 | - } while (n > 0); | |
| 923 | + //} while (n > 0); | |
| 907 | 924 | |
| 908 | 925 | } // endif: Hub connection had been established |
| 909 | 926 | ... | ... |
src/vo/GVOHub.cpp
| ... | ... | @@ -27,6 +27,7 @@ |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| 28 | 28 | #ifdef HAVE_CONFIG_H |
| 29 | 29 | #include <config.h> |
| 30 | +#include <errno.h> | |
| 30 | 31 | #endif |
| 31 | 32 | #include <cstdlib> // std::getenv() function |
| 32 | 33 | #include <cstdio> // std::fopen(), etc. functions |
| ... | ... | @@ -186,7 +187,7 @@ void GVOHub::start(void) |
| 186 | 187 | * |
| 187 | 188 | * |
| 188 | 189 | ***************************************************************************/ |
| 189 | -void GVOHub::register_service(const socklen_t& sock) | |
| 190 | +void GVOHub::ping_service(const socklen_t& sock) | |
| 190 | 191 | { |
| 191 | 192 | printf("Registration request received\n"); |
| 192 | 193 | // Declare message |
| ... | ... | @@ -195,11 +196,47 @@ void GVOHub::register_service(const socklen_t& sock) |
| 195 | 196 | // Set methodResponse elts |
| 196 | 197 | msg.append("<?xml version=\"1.0\"?>\n"); |
| 197 | 198 | msg.append("<methodResponse>\n"); |
| 198 | - msg.append("<params>\n"); | |
| 199 | - msg.append("<param><value><struct>\n"); | |
| 199 | + msg.append("</methodResponse>\n"); | |
| 200 | + int length = msg.length(); | |
| 201 | + | |
| 202 | + int n = write(sock,msg.c_str(),length); | |
| 203 | + if (n < 0) { | |
| 204 | + printf("Could not write socket buffer.\n"); | |
| 205 | + std::string msg = "Could not write socket buffer."; | |
| 206 | + throw GException::invalid_value(G_HANDLE_REQUEST, msg); | |
| 207 | + } | |
| 208 | + | |
| 209 | + printf("Response message sent\n"); | |
| 210 | + //Return | |
| 211 | + return; | |
| 212 | +} | |
| 213 | + | |
| 214 | +/***********************************************************************//** | |
| 215 | + * @brief | |
| 216 | + * | |
| 217 | + * | |
| 218 | + ***************************************************************************/ | |
| 219 | +void GVOHub::register_service(const GXml& xml, const socklen_t& sock) | |
| 220 | +{ | |
| 221 | + printf("Registration request received\n"); | |
| 222 | + // Declare message | |
| 223 | + std::string msg = ""; | |
| 224 | + std::string translator = "http://localhost:8001/"; | |
| 225 | + //std::string client_name = get_response_value(xml, "samp.name"); | |
| 226 | + | |
| 227 | + //Clients[m_nb_clients].client_name = get_response_value(xml, "samp.name"); | |
| 228 | + //printf("Client name %s",Clients[m_nb_clients].client_name.c_str()); | |
| 229 | + //m_nb_clients ++; | |
| 230 | + | |
| 231 | + // Set methodResponse elts | |
| 232 | + msg.append("<?xml version=\"1.0\"?>\n"); | |
| 233 | + msg.append("<methodResponse>\n"); | |
| 234 | + msg.append("\t<params>\n"); | |
| 235 | + msg.append("\t\t<param>\n\t\t\t<value>\n\t\t\t\t<struct>\n"); | |
| 200 | 236 | msg.append("<member><name>samp.private-key</name><value><string>client-key:" + m_hub_id + "</string></value></member>\n"); |
| 201 | - msg.append("<member><name>samp.hub-id</name><value><string>client-id:" + m_hub_id + "</string></value></member>\n"); | |
| 237 | + msg.append("<member><name>samp.hub-id</name><value><string>hub-id:" + m_hub_id + "</string></value></member>\n"); | |
| 202 | 238 | msg.append("<member><name>samp.self-id</name><value><string>client-id:" + m_client_id + "</string></value></member>\n"); |
| 239 | + msg.append("<member><name>samp.url-translator</name><value><string>" + translator + "</string></value></member>\n"); | |
| 203 | 240 | msg.append("</struct></value></param>\n"); |
| 204 | 241 | msg.append("</params>\n"); |
| 205 | 242 | msg.append("</methodResponse>\n"); |
| ... | ... | @@ -208,10 +245,12 @@ void GVOHub::register_service(const socklen_t& sock) |
| 208 | 245 | |
| 209 | 246 | int n = write(sock,msg.c_str(),length); |
| 210 | 247 | if (n < 0) { |
| 248 | + printf("Could not write socket buffer.\n"); | |
| 211 | 249 | std::string msg = "Could not write socket buffer."; |
| 212 | 250 | throw GException::invalid_value(G_HANDLE_REQUEST, msg); |
| 213 | 251 | } |
| 214 | 252 | |
| 253 | + printf("Response message sent\n"); | |
| 215 | 254 | //Return |
| 216 | 255 | return; |
| 217 | 256 | } |
| ... | ... | @@ -222,10 +261,10 @@ void GVOHub::register_service(const socklen_t& sock) |
| 222 | 261 | * |
| 223 | 262 | * |
| 224 | 263 | ***************************************************************************/ |
| 225 | -void GVOHub::unregister(void) | |
| 264 | +void GVOHub::unregister(const socklen_t& sock) | |
| 226 | 265 | { |
| 227 | 266 | |
| 228 | - // Return | |
| 267 | + close(sock); | |
| 229 | 268 | return; |
| 230 | 269 | } |
| 231 | 270 | |
| ... | ... | @@ -234,13 +273,33 @@ void GVOHub::unregister(void) |
| 234 | 273 | * |
| 235 | 274 | * |
| 236 | 275 | ***************************************************************************/ |
| 237 | -void GVOHub::register_metadata(const GXml& xml) | |
| 276 | +void GVOHub::register_metadata(const GXml& xml,const socklen_t& sock) | |
| 238 | 277 | { |
| 239 | 278 | printf("Client Metadata received\n"); |
| 240 | 279 | // Search for metadata values to store |
| 241 | 280 | std::string client_name = get_response_value(xml, "samp.name"); |
| 242 | - //printf("Client Metadata : \n" + client_name.c_str()); | |
| 243 | - // Return | |
| 281 | + //std::cout("Client Metadata : \n" + client_name.c_str()); | |
| 282 | + printf("\nClient Metadata : Name %s\n", client_name.c_str()); | |
| 283 | + fflush(stdout); | |
| 284 | + // Declare message | |
| 285 | + std::string msg = ""; | |
| 286 | + | |
| 287 | + // Set methodResponse elts | |
| 288 | + msg.append("<?xml version=\"1.0\"?>\n"); | |
| 289 | + msg.append("<methodResponse>\n"); | |
| 290 | + msg.append("</methodResponse>\n"); | |
| 291 | + | |
| 292 | + int length = msg.length(); | |
| 293 | + | |
| 294 | + int n = write(sock,msg.c_str(),length); | |
| 295 | + if (n < 0) { | |
| 296 | + printf("Could not write socket buffer.\n"); | |
| 297 | + std::string msg = "Could not write socket buffer."; | |
| 298 | + throw GException::invalid_value(G_HANDLE_REQUEST, msg); | |
| 299 | + } | |
| 300 | + | |
| 301 | + printf("Response message sent\n"); | |
| 302 | + //Return | |
| 244 | 303 | return; |
| 245 | 304 | } |
| 246 | 305 | |
| ... | ... | @@ -316,8 +375,10 @@ void GVOHub::init_members(void) |
| 316 | 375 | m_hub_id = "b79884e0"; |
| 317 | 376 | m_client_id.clear(); |
| 318 | 377 | m_socket = -1; // Signals no socket |
| 319 | - | |
| 378 | + m_nb_clients = 0; // No registered clients at initialization | |
| 379 | + //client_metadata * Clients = new client_metadata[5]; | |
| 320 | 380 | // Return |
| 381 | + Clients = new client_metadata[5]; | |
| 321 | 382 | return; |
| 322 | 383 | } |
| 323 | 384 | |
| ... | ... | @@ -460,14 +521,14 @@ std::string GVOHub::get_hub_lockfile(void) const |
| 460 | 521 | void GVOHub::handle_request(const socklen_t& sock) |
| 461 | 522 | { |
| 462 | 523 | // Initialize buffer |
| 463 | - char buffer[1024]; | |
| 464 | - bzero(buffer,1024); | |
| 524 | + char buffer[4096]; | |
| 525 | + bzero(buffer,4096); | |
| 465 | 526 | |
| 466 | 527 | // Declare empty XML document |
| 467 | 528 | GXml xml; |
| 468 | 529 | |
| 469 | 530 | // Read buffer |
| 470 | - int n = read(sock,buffer,1024); | |
| 531 | + int n = read(sock,buffer,4096); | |
| 471 | 532 | if (n < 0) { |
| 472 | 533 | std::string msg = "Could not read socket buffer."; |
| 473 | 534 | throw GException::invalid_value(G_HANDLE_REQUEST, msg); |
| ... | ... | @@ -480,6 +541,10 @@ void GVOHub::handle_request(const socklen_t& sock) |
| 480 | 541 | // If found then convert text into XML document |
| 481 | 542 | if (start != std::string::npos) { |
| 482 | 543 | xml = GXml(response.substr(start, std::string::npos)); |
| 544 | + } else { | |
| 545 | + //No XML tag found. | |
| 546 | + return; | |
| 547 | + | |
| 483 | 548 | } |
| 484 | 549 | |
| 485 | 550 | std::string method_called = ""; |
| ... | ... | @@ -495,13 +560,49 @@ void GVOHub::handle_request(const socklen_t& sock) |
| 495 | 560 | // endif: connection has been established |
| 496 | 561 | //std::string method_called = get_response_value(xml, "methodName"); |
| 497 | 562 | if (method_called.compare("samp.hub.register") == 0) { |
| 498 | - register_service(sock); | |
| 563 | + register_service(xml, sock); | |
| 499 | 564 | } |
| 500 | 565 | if (method_called.compare("samp.hub.unregister") == 0) { |
| 501 | - unregister(); | |
| 566 | + unregister(sock); | |
| 502 | 567 | } |
| 503 | 568 | if (method_called.compare("samp.hub.declareMetadata") == 0) { |
| 504 | - register_metadata(xml); | |
| 569 | + register_metadata(xml,sock); | |
| 570 | + } | |
| 571 | + if (method_called.compare("samp.hub.ping") == 0) { | |
| 572 | + ping_service(sock); | |
| 573 | + } | |
| 574 | + if (method_called.compare("samp.hub.getMetadata") == 0) { | |
| 575 | + ping_service(sock); | |
| 576 | + } | |
| 577 | + if (method_called.compare("samp.hub.declareSubscriptions") == 0) { | |
| 578 | + ping_service(sock); | |
| 579 | + } | |
| 580 | + if (method_called.compare("samp.hub.getSubscriptions") == 0) { | |
| 581 | + ping_service(sock); | |
| 582 | + } | |
| 583 | + if (method_called.compare("samp.hub.getRegisteredClients") == 0) { | |
| 584 | + ping_service(sock); | |
| 585 | + } | |
| 586 | + if (method_called.compare("samp.hub.getSubscribedClients") == 0) { | |
| 587 | + ping_service(sock); | |
| 588 | + } | |
| 589 | + if (method_called.compare("samp.hub.notify") == 0) { | |
| 590 | + ping_service(sock); | |
| 591 | + } | |
| 592 | + if (method_called.compare("samp.hub.notifyAll") == 0) { | |
| 593 | + ping_service(sock); | |
| 594 | + } | |
| 595 | + if (method_called.compare("samp.hub.call") == 0) { | |
| 596 | + ping_service(sock); | |
| 597 | + } | |
| 598 | + if (method_called.compare("samp.hub.callAll") == 0) { | |
| 599 | + ping_service(sock); | |
| 600 | + } | |
| 601 | + if (method_called.compare("samp.hub.callAndWait") == 0) { | |
| 602 | + ping_service(sock); | |
| 603 | + } | |
| 604 | + if (method_called.compare("samp.hub.reply") == 0) { | |
| 605 | + ping_service(sock); | |
| 505 | 606 | } |
| 506 | 607 | // Return |
| 507 | 608 | return; |
| ... | ... | @@ -517,36 +618,61 @@ void GVOHub::handle_request(const socklen_t& sock) |
| 517 | 618 | void GVOHub::start_hub(void) |
| 518 | 619 | { |
| 519 | 620 | struct sockaddr_in serv_addr,cli_addr; |
| 520 | - int portno,pid; | |
| 521 | - socklen_t hub_socket,newsocket,sockfd,clilen; | |
| 522 | - | |
| 621 | + int max_sd, portno,pid,max_clients = 10, i,activity,addrlen; | |
| 622 | + socklen_t hub_socket,newsocket,sockfd,clilen, client_socket[10]; | |
| 623 | + int opt = 1; | |
| 523 | 624 | // Prepare TCP/IP structure |
| 524 | 625 | bzero((char *) &serv_addr, sizeof(serv_addr)); |
| 525 | 626 | portno = 8001; |
| 526 | 627 | serv_addr.sin_family = AF_INET; |
| 527 | 628 | serv_addr.sin_addr.s_addr = INADDR_ANY; |
| 528 | 629 | serv_addr.sin_port = htons(portno); |
| 630 | + | |
| 631 | + //set of socket descriptors | |
| 632 | + fd_set readfds; | |
| 633 | + | |
| 634 | + //initialise all client_socket[] to 0 so not checked | |
| 635 | + for (i = 0; i < max_clients; i++) | |
| 636 | + { | |
| 637 | + client_socket[i] = 0; | |
| 638 | + } | |
| 639 | + | |
| 529 | 640 | hub_socket = socket(AF_INET, SOCK_STREAM, 0); |
| 641 | + | |
| 642 | + //Creation of hub main socket | |
| 530 | 643 | if (hub_socket < 0) { |
| 531 | 644 | std::string msg = "Socket could not be created."; |
| 532 | 645 | throw GException::invalid_value(G_START_HUB, msg); |
| 533 | 646 | } |
| 534 | 647 | |
| 648 | + //set hub main socket to allow multiple connections | |
| 649 | + if( setsockopt(hub_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) | |
| 650 | + { | |
| 651 | + std::string msg = "Socket could not be set to multiple connetcions."; | |
| 652 | + throw GException::invalid_value(G_START_HUB, msg); | |
| 653 | + } | |
| 654 | + | |
| 535 | 655 | // Server socket is opened. Now, bind it to the port, with family etc. |
| 536 | 656 | if (bind(hub_socket, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { |
| 537 | 657 | std::string msg = "Could not bind to server socket."; |
| 538 | 658 | throw GException::invalid_value(G_START_HUB, msg); |
| 539 | 659 | } |
| 540 | 660 | |
| 541 | - // Now start listening for the clients: 5 requests simultaneously maximum | |
| 542 | - listen(hub_socket,5); | |
| 661 | + // Now start listening for the clients: 5 requests simultaneously pending maximum | |
| 662 | + if (listen(hub_socket,5) < 0) | |
| 663 | + { | |
| 664 | + std::string msg = "Main hub socket couldn't start litening"; | |
| 665 | + throw GException::invalid_value(G_START_HUB, msg); | |
| 666 | + } | |
| 667 | + | |
| 543 | 668 | clilen = sizeof(cli_addr); |
| 669 | + | |
| 544 | 670 | while (1) { |
| 671 | + | |
| 672 | + | |
| 673 | + // Accept connection from the client | |
| 545 | 674 | |
| 546 | - // Accept actual connection from the client | |
| 547 | -//std::cout << "Now accept connection the socket" << std::endl; | |
| 548 | 675 | newsocket = accept(hub_socket, (struct sockaddr *)&cli_addr, &clilen); |
| 549 | -//std::cout << "Connection accepted" << std::endl; | |
| 550 | 676 | if (newsocket < 0) { |
| 551 | 677 | std::string msg = "Client connection to socket not accepted."; |
| 552 | 678 | throw GException::invalid_value(G_START_HUB, msg); |
| ... | ... | @@ -554,7 +680,7 @@ void GVOHub::start_hub(void) |
| 554 | 680 | |
| 555 | 681 | // Create child process to handle the request |
| 556 | 682 | pid = fork(); |
| 557 | -//std::cout << "Called fork " << pid << std::endl; | |
| 683 | + | |
| 558 | 684 | if (pid < 0) { |
| 559 | 685 | std::string msg = "Not child process created."; |
| 560 | 686 | throw GException::invalid_value(G_START_HUB, msg); |
| ... | ... | @@ -565,9 +691,9 @@ void GVOHub::start_hub(void) |
| 565 | 691 | exit(0); |
| 566 | 692 | } |
| 567 | 693 | else { |
| 568 | -//std::cout << "Now close the socket" << std::endl; | |
| 694 | + | |
| 569 | 695 | close(newsocket); |
| 570 | -//std::cout << "Socket closed" << std::endl; | |
| 696 | + | |
| 571 | 697 | } |
| 572 | 698 | |
| 573 | 699 | } |
| ... | ... | @@ -605,11 +731,13 @@ std::string GVOHub::get_response_value(const GXml& xml, |
| 605 | 731 | if (node != NULL) { |
| 606 | 732 | int num = node->elements("member"); |
| 607 | 733 | for (int i = 0; i < num; ++i) { |
| 734 | + std::cout << i << std::endl; | |
| 735 | + std::cout << *(node->element("member", i)) << std::cout; | |
| 608 | 736 | const GXmlNode* member = node->element("member", i); |
| 609 | - const GXmlNode* member_name = member->element("name", 0); | |
| 737 | + //const GXmlNode* member_name = member->element("name", 0); | |
| 610 | 738 | std::string one_name; |
| 611 | 739 | std::string one_value; |
| 612 | - get_name_value_pair(member_name, one_name, one_value); | |
| 740 | + get_name_value_pair(member, one_name, one_value); | |
| 613 | 741 | if (one_name == name) { |
| 614 | 742 | value = one_value; |
| 615 | 743 | break; | ... | ... |