| | |
| | | static Logger *logger = LoggerFactory::getLogger(); |
| | | |
| | | void BusServerSocket::foreach_subscripters(std::function<void(SHMKeySet *, int)> cb) { |
| | | SHMTopicSubMap *topic_sub_map = mem_pool_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | SHMTopicSubMap *topic_sub_map = shm_mm_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | SHMKeySet *subscripter_set; |
| | | SHMKeySet::iterator set_iter; |
| | | SHMTopicSubMap::iterator map_iter; |
| | |
| | | int key; |
| | | for(int i = 0; i < length; i++) { |
| | | key = keys[i]; |
| | | SHMTopicSubMap *topic_sub_map = mem_pool_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | SHMTopicSubMap *topic_sub_map = shm_mm_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | SHMKeySet *subscripter_set; |
| | | SHMKeySet::iterator set_iter; |
| | | SHMTopicSubMap::iterator map_iter; |
| | |
| | | |
| | | BusServerSocket::BusServerSocket() { |
| | | logger->debug("BusServerSocket Init"); |
| | | shm_socket = shm_open_socket(SHM_SOCKET_DGRAM); |
| | | shm_socket = shm_socket_open(SHM_SOCKET_DGRAM); |
| | | topic_sub_map = NULL; |
| | | |
| | | } |
| | | |
| | | BusServerSocket::~BusServerSocket() { |
| | | SHMKeySet *subscripter_set; |
| | | SHMTopicSubMap::iterator map_iter; |
| | | |
| | | stop(); |
| | | |
| | | if(topic_sub_map != NULL) { |
| | | for (map_iter = topic_sub_map->begin(); map_iter != topic_sub_map->end(); map_iter++) { |
| | | subscripter_set = map_iter->second; |
| | | if(subscripter_set != NULL) { |
| | | subscripter_set->clear(); |
| | | mm_free((void *)subscripter_set); |
| | | } |
| | | |
| | | } |
| | | topic_sub_map->clear(); |
| | | mem_pool_free_by_key(SHM_BUS_MAP_KEY); |
| | | } |
| | | shm_close_socket(shm_socket); |
| | | logger->debug("BusServerSocket destory 3"); |
| | | destroy(); |
| | | } |
| | | |
| | | |
| | |
| | | * 启动bus |
| | | * |
| | | * @return 0 成功, 其他值 失败的错误码 |
| | | */ |
| | | */ |
| | | int BusServerSocket::start(){ |
| | | topic_sub_map = mem_pool_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | topic_sub_map = shm_mm_attach<SHMTopicSubMap>(SHM_BUS_MAP_KEY); |
| | | |
| | | run_pubsub_proxy(); |
| | | // 进程停止的时候,预留3秒资源回收的时间。否则,会发生调用close的时候,共享内存的资源还没来得及回收进程就退出了 |
| | | _run_proxy_(); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | if( shm_socket->key <= 0) { |
| | | return -1; |
| | | } |
| | | // snprintf(buf, 128, "%sstop%s%s%s%s", ACTION_LIDENTIFIER, ACTION_RIDENTIFIER, TOPIC_LIDENTIFIER, "", TOPIC_RIDENTIFIER); |
| | | // return shm_sendto(shm_socket, buf, strlen(buf), shm_socket->key, NULL, 0); |
| | | bus_head_t head = {}; |
| | | memcpy(head.action, "stop", sizeof(head.action)); |
| | | head.topic_size = 0; |
| | |
| | | void *buf; |
| | | int size = ShmModSocket::get_bus_sendbuf(head, NULL, 0, NULL, 0, &buf); |
| | | if(size > 0) { |
| | | ret = client.sendandrecv_unsafe( buf, size, shm_socket->key, NULL, NULL); |
| | | ret = client.sendto( buf, size, shm_socket->key); |
| | | free(buf); |
| | | return ret; |
| | | } else { |
| | | return -1; |
| | | } |
| | | |
| | | } |
| | | |
| | | int BusServerSocket::destroy() { |
| | | SHMKeySet *subscripter_set; |
| | | SHMTopicSubMap::iterator map_iter; |
| | | if(topic_sub_map != NULL) { |
| | | for (map_iter = topic_sub_map->begin(); map_iter != topic_sub_map->end(); map_iter++) { |
| | | subscripter_set = map_iter->second; |
| | | if(subscripter_set != NULL) { |
| | | subscripter_set->clear(); |
| | | mm_free((void *)subscripter_set); |
| | | } |
| | | |
| | | } |
| | | topic_sub_map->clear(); |
| | | shm_mm_free_by_key(SHM_BUS_MAP_KEY); |
| | | } |
| | | shm_socket_close(shm_socket); |
| | | logger->debug("BusServerSocket destory 3"); |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | |
| | | std::vector<int>::iterator vector_iter; |
| | | |
| | | int send_key; |
| | | int rv; |
| | | struct timespec timeout = {1,0}; |
| | | |
| | | if( (map_iter = topic_sub_map->find(topic) ) != topic_sub_map->end()) { |
| | | |
| | | subscripter_set = map_iter->second; |
| | | for(set_iter = subscripter_set->begin(); set_iter != subscripter_set->end(); set_iter++) { |
| | | send_key = *set_iter; |
| | | // printf("_proxy_pub send before %d \n", send_key); |
| | | if (shm_sendto(shm_socket, buf, size, send_key, &timeout) == EBUS_CLOSED ) { |
| | | //对方已关闭的连接放到待删除队列里。如果直接删除会让iter指针出现错乱 |
| | | subscripter_to_del.push_back(send_key); |
| | | } else { |
| | | // printf("_proxy_pub send after: %d \n", send_key); |
| | | // logger->debug("_proxy_pub send before %d \n", send_key); |
| | | rv = shm_sendto(shm_socket, buf, size, send_key, &timeout, BUS_TIMEOUT_FLAG); |
| | | if(rv == 0) { |
| | | continue; |
| | | } |
| | | |
| | | |
| | | //对方已关闭的或者对应的进程被kill掉的连接放到待删除队列里。如果直接删除会让iter指针出现错乱 |
| | | subscripter_to_del.push_back(send_key); |
| | | } |
| | | |
| | | // 删除已关闭的端 |
| | |
| | | } |
| | | } |
| | | |
| | | void * BusServerSocket::run_pubsub_proxy() { |
| | | // pthread_detach(pthread_self()); |
| | | |
| | | // 运行代理 |
| | | void * BusServerSocket::_run_proxy_() { |
| | | int size; |
| | | int key; |
| | | char * action, *topic, *topics, *buf, *content; |
| | |
| | | bus_head_t head; |
| | | |
| | | const char *topic_delim = ","; |
| | | // printf("run_pubsub_proxy server receive before\n"); |
| | | // logger.debug("_run_proxy_ server receive before\n"); |
| | | while(shm_recvfrom(shm_socket, (void **)&buf, &size, &key) == 0) { |
| | | // printf("run_pubsub_proxy server recvfrom %d after: %s \n", key, buf); |
| | | // logger.debug("_run_proxy_ server recvfrom %d after: %s \n", key, buf); |
| | | head = ShmModSocket::decode_bus_head(buf); |
| | | topics = buf + BUS_HEAD_SIZE; |
| | | action = head.action; |
| | | // printf("run_pubsub_proxy : %s\n", action); |
| | | // logger.debug("_run_proxy_ : %s\n", action); |
| | | if(strcmp(action, "sub") == 0) { |
| | | // 订阅支持多主题订阅 |
| | | topic = strtok(topics, topic_delim); |
| | | // printf("run_pubsub_proxy topic = %s\n", topic); |
| | | // logger.debug("_run_proxy_ topic = %s\n", topic); |
| | | while(topic) { |
| | | _proxy_sub(trim(topic, 0), key); |
| | | topic = strtok(NULL, topic_delim); |
| | |
| | | |
| | | } |
| | | else if(strcmp(action, "desub") == 0) { |
| | | // printf("desub topic=%s,%s,%d\n", topics, trim(topics, 0), strcmp(trim(topics, 0), "")); |
| | | // logger.debug("desub topic=%s,%s,%d\n", topics, trim(topics, 0), strcmp(trim(topics, 0), "")); |
| | | if(strcmp(trim(topics, 0), "") == 0) { |
| | | // 取消所有订阅 |
| | | _proxy_desub_all(key); |
| | |
| | | free(buf); |
| | | break; |
| | | } else { |
| | | logger->error( "BusServerSocket::run_pubsub_proxy : unrecognized action %s", action); |
| | | logger->error( "BusServerSocket::_run_proxy_ : unrecognized action %s", action); |
| | | } |
| | | free(buf); |
| | | } |
| | | |
| | | |
| | | shm_sendto(shm_socket, "stop_finished", strlen( "stop_finished") +1, key); |
| | | |
| | | return NULL; |
| | | } |