wangzhengquan
2021-02-25 f52f2c2828047c2f30d30fc1fe2b54d8db146d49
src/socket/bus_server_socket.cpp
@@ -6,7 +6,7 @@
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;
@@ -22,24 +22,14 @@
      }
   }
}
// bool BusServerSocket::include_in_keys(int key, int keys[], size_t length) {
//    if(length == 0) {
//       return false;
//    }
//    for(int i = 0; i < length; i++) {
//       if(keys[i] == key)
//          return true;
//    }
//    return false;
// }
size_t BusServerSocket::remove_subscripters(int keys[], size_t length) {
   size_t count = 0;
   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;
@@ -62,33 +52,13 @@
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;
   logger->debug("BusServerSocket destory 1");
   stop();
   logger->debug("BusServerSocket destory 2");
   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();
}
@@ -109,39 +79,56 @@
 * 启动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;
}
int  BusServerSocket::stop(){
   int ret;
   logger->debug("====>stopping");
   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;
   head.content_size = 0;
  ShmModSocket client;
   void *buf;
   int size = ShmModSocket::get_bus_sendbuf(head, NULL, 0, NULL,  0, &buf);
   if(size > 0) {
      ret = shm_sendandrecv_unsafe(shm_socket, 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;
}
/*
@@ -206,21 +193,21 @@
   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);
      }
      // 删除已关闭的端
@@ -235,8 +222,9 @@
   }
}
void * BusServerSocket::run_pubsub_proxy() {
   // pthread_detach(pthread_self());
// 运行代理
void * BusServerSocket::_run_proxy_() {
   int size;
   int key;
   char * action, *topic, *topics, *buf, *content;
@@ -245,17 +233,17 @@
   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 recv after: %s \n", 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, %s \n", action, topics);
// 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);
@@ -263,7 +251,7 @@
      } 
      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);
@@ -283,89 +271,15 @@
      }  
      else if(strcmp(action, "stop") == 0) {
         logger->info( "Stopping Bus...");
         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);
   }
   logger->info( "Stopping Bus...");
   shm_sendto(shm_socket, "stop_finished", strlen( "stop_finished") +1, key);
   return NULL;
}
/**
 * deprecate
 * @str "<**sub**>{经济}"
 */
int BusServerSocket::parse_pubsub_topic(char *str, size_t size, char **_action, char **_topic, size_t *head_len ) {
 char *ptr = str;
 char *str_end_ptr = str + size;
 char *action_start_ptr;
 char *action_end_ptr;
 size_t action_len = 0;
 char *topic_start_ptr;
 char *topic_end_ptr;
 size_t topic_len = 0;
 // if (strlen(identifier) > strlen(str)) {
 //  return 0;
 // }
 if (strncmp(ptr, ACTION_LIDENTIFIER, strlen(ACTION_LIDENTIFIER)) == 0) {
  ptr += strlen(ACTION_LIDENTIFIER);
  action_start_ptr = ptr;
  while(strncmp(++ptr, ACTION_RIDENTIFIER, strlen(ACTION_RIDENTIFIER)) != 0) {
    if(ptr >= str_end_ptr) {
      return 0;
    }
  }
// printf("%s\n", ptr);
  action_end_ptr = ptr;
  action_len = action_end_ptr - action_start_ptr;
  ptr += strlen(ACTION_RIDENTIFIER);
// printf("%s\n", ptr);
// printf("%s\n", str_end_ptr-1);
  if(strncmp(ptr, TOPIC_LIDENTIFIER, strlen(TOPIC_LIDENTIFIER)) == 0 ) {
    topic_start_ptr = ptr+strlen(TOPIC_LIDENTIFIER);
    while(strncmp(++ptr, TOPIC_RIDENTIFIER, strlen(TOPIC_RIDENTIFIER)) != 0) {
      if(ptr >= str_end_ptr) {
        return 0;
      }
    }
    topic_end_ptr = ptr;
    topic_len = topic_end_ptr - topic_start_ptr;
    ptr += strlen(TOPIC_RIDENTIFIER);
  } else {
    return 0;
  }
 } else {
  return 0;
 }
 char *topic = (char *)malloc(topic_len+1);
 strncpy(topic, topic_start_ptr, topic_len);
 *(topic+topic_len) = '\0';
 *_topic = topic;
 char *action = (char *)malloc(action_len+1);
 strncpy(action, action_start_ptr, action_len);
 *(action+action_len) = '\0';
 *_action = action;
 *head_len = ptr-str;
 return 1;
}