Преглед изворни кода

Merge branch 'master' of http://local.beijingyongan.com:3000/linux-dev/ya-serv

lixioayao пре 6 година
родитељ
комит
42dfe4e53f
23 измењених фајлова са 744 додато и 195 уклоњено
  1. 2 1
      Makefile.am
  2. 118 11
      area.cpp
  3. 26 0
      area.h
  4. 27 10
      card.cpp
  5. 6 4
      card.h
  6. 3 2
      card_base.cpp
  7. 48 45
      card_message_handle.cpp
  8. 7 0
      card_message_handle.h
  9. 19 17
      card_person.cpp
  10. 6 9
      db/db_card.cpp
  11. 3 3
      db/db_card.h
  12. 124 0
      forbid_staff_down_mine.cpp
  13. 49 0
      forbid_staff_down_mine.h
  14. 26 13
      main.cpp
  15. 84 43
      module_service/module_meta_date_changed.cpp
  16. 10 6
      module_service/module_meta_date_changed.h
  17. 17 5
      net-service.cpp
  18. 16 1
      test.cpp
  19. 3 0
      websocket/constdef.h
  20. 56 7
      worker.cpp
  21. 16 0
      worker.h
  22. 76 18
      znet.cpp
  23. 2 0
      znet.h

+ 2 - 1
Makefile.am

@@ -21,7 +21,8 @@ SRC_MAIN= ant.cpp area.cpp base64.cpp bindmorecard.cpp mine_business.cpp card_ar
     	  card.cpp card_message_handle.cpp cardMgr.cpp card_path.cpp card_person.cpp crc.cpp geo_hash.cpp \
     	  card.cpp card_message_handle.cpp cardMgr.cpp card_path.cpp card_person.cpp crc.cpp geo_hash.cpp \
 		  landmark.cpp line_fit.cpp loc_point.cpp loc_tool.cpp message.cpp message_file.cpp mine.cpp \
 		  landmark.cpp line_fit.cpp loc_point.cpp loc_tool.cpp message.cpp message_file.cpp mine.cpp \
 		  net-service.cpp point.cpp select_tool.cpp  special_area.cpp tdoa_sync.cpp visit.cpp \
 		  net-service.cpp point.cpp select_tool.cpp  special_area.cpp tdoa_sync.cpp visit.cpp \
-		  web-client.cpp worker.cpp event.cpp znet.cpp ya_setting.cpp area_business.cpp
+		  web-client.cpp worker.cpp event.cpp znet.cpp ya_setting.cpp area_business.cpp\
+		  forbid_staff_down_mine.cpp
 
 
 AM_SOURCES=$(SRC_MONKEYCAR) $(SRC_MODULE_SERVICE) $(SRC_MAIN) $(SRC_MAIN_EVENT)
 AM_SOURCES=$(SRC_MONKEYCAR) $(SRC_MODULE_SERVICE) $(SRC_MAIN) $(SRC_MAIN_EVENT)
 
 

+ 118 - 11
area.cpp

@@ -4,6 +4,7 @@
 #include "log.h"
 #include "log.h"
 
 
 #include <area.h>
 #include <area.h>
+#include "worker.h"
 #include "point.h"
 #include "point.h"
 #include "tool_time.h"
 #include "tool_time.h"
 #include "common_tool.h"
 #include "common_tool.h"
@@ -81,9 +82,35 @@ area::area(int id,int limit_count_person, int limit_time_person,double scale,int
 		m_event_vehicle_count = false;
 		m_event_vehicle_count = false;
 		m_event_person_show_count = false;
 		m_event_person_show_count = false;
 		m_event_vehicle_show_count = false;
 		m_event_vehicle_show_count = false;
+
+		m_frozen_count.store(0);
     }
     }
 
 
 
 
+void area::change_business(uint32_t new_bits)
+{
+	worker*w=worker::instance();
+
+	uint32_t del=((m_area_type^new_bits)|m_area_type)^m_area_type;
+	uint32_t add=((m_area_type^new_bits)|new_bits)^new_bits;
+
+	task*t =task::alloc<message_change_business>();
+
+	t->m_cmd_code=0x10001; //区域业务类型修改的编码
+	t->m_hash_id=0;        //这个不用
+
+	auto&mcb=t->body<message_change_business>();
+	mcb.area_id=m_id;
+	mcb.del_list=area_business::get_instance_list(del,m_id);
+	mcb.add_list=area_business::get_instance_list(add,m_id);
+	mcb.new_list=area_business::get_instance_list(new_bits,m_id);
+	mcb.ref_count.store(w->num_thread());
+
+	add_frozen_count(w->num_thread()+1);
+
+	w->broadcast(t);
+}
+
 void area::on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
 void area::on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
 {
 {
 	a->m_last_time=tool_time::now_to_ms();
 	a->m_last_time=tool_time::now_to_ms();
@@ -389,15 +416,19 @@ void area_list::init_from_db(int id/*=-1*/)
         else
         else
         {
         {
             auto tmp_ptr = area_list::instance()->get(id);
             auto tmp_ptr = area_list::instance()->get(id);
+			bool newobj=false;
+			
             if(!tmp_ptr)
             if(!tmp_ptr)
             {
             {
 				tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
 				tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
-                area_list::instance()->add(id, tmp_ptr);
+				newobj=true;
             }
             }
+
             tmp_ptr->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle);
             tmp_ptr->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle);
             tmp_ptr->m_speed=std::move(map_);
             tmp_ptr->m_speed=std::move(map_);
             tmp_ptr->m_bound=init_path(path,area_id);
             tmp_ptr->m_bound=init_path(path,area_id);
             tmp_ptr->m_is_work_area = is_work_area;
             tmp_ptr->m_is_work_area = is_work_area;
+
             for(const auto &p : tmp_ptr->m_bound)
             for(const auto &p : tmp_ptr->m_bound)
                 log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
                 log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
 
 
@@ -405,6 +436,15 @@ void area_list::init_from_db(int id/*=-1*/)
                      ,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
                      ,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
                      id,over_count_person, over_time_person,scale,map_id,area_type_id,
                      id,over_count_person, over_time_person,scale,map_id,area_type_id,
                      over_count_vehicle,over_time_vehicle);
                      over_count_vehicle,over_time_vehicle);
+
+			if(newobj)
+			{
+				area_list::instance()->add(id, tmp_ptr);
+			}
+			else
+			{
+				tmp_ptr->change_business(b_type);
+			}
         }
         }
     }
     }
 
 
@@ -481,9 +521,11 @@ void area_tool::on_point(const std::shared_ptr<card_location_base>& c,const poin
 		areas.push_back(area_);
 		areas.push_back(area_);
 	}
 	}
 	else
 	else
+	{
 		std::sort(areas.begin(),areas.end(),[](const std::shared_ptr<area>&l,const std::shared_ptr<area>&r){
 		std::sort(areas.begin(),areas.end(),[](const std::shared_ptr<area>&l,const std::shared_ptr<area>&r){
 				return l->id()<r->id();
 				return l->id()<r->id();
 				});
 				});
+	}
 
 
 	auto c1=m_hover_list.begin(),ce=m_hover_list.end();
 	auto c1=m_hover_list.begin(),ce=m_hover_list.end();
 	auto a1=areas.begin() ,ae=areas.end();
 	auto a1=areas.begin() ,ae=areas.end();
@@ -492,35 +534,72 @@ void area_tool::on_point(const std::shared_ptr<card_location_base>& c,const poin
 
 
 	while (c1!=ce && a1!=ae)
 	while (c1!=ce && a1!=ae)
 	{
 	{
-		if ((*c1)->id()<(*a1)->id()) 
+		if ((*c1)->id()<(*a1)->id()) //离开区域
 		{ 
 		{ 
-			(*c1)->m_area->on_leave(*c1, c);
+			if((*c1)->m_area->get_frozen_count()==0)//如果该区域未在修改中,调用on_leave
+			{
+				(*c1)->m_area->on_leave(*c1, c);
+			}
+			else//否则,该区域持续保存在卡的区域列表,等待修改完成
+			{
+				nlist.push_back(*c1);
+				log_warn("丢弃离开区域事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+			}
 			++c1;
 			++c1;
 		}
 		}
-		else if ((*a1)->id()<(*c1)->id()) 
+		else if ((*a1)->id()<(*c1)->id()) //进入新区域
 		{
 		{
-			nlist.push_back(std::make_shared<area_hover>(*a1,pt));
-			(*a1)->on_enter(nlist.back(),c);
+			if((*a1)->get_frozen_count()==0)////如果该区域未在修改中,执行正常逻辑
+			{
+				nlist.push_back(std::make_shared<area_hover>(*a1,pt));
+				(*a1)->on_enter(nlist.back(),c);
+			}
+			else//丢弃本次进入的点,等待修改完成
+			{
+				log_warn("丢弃进入区域事件,cardid=%d,area_id=%d",c->m_id,(*a1)->id());
+			}
 			++a1;
 			++a1;
 		}
 		}
-		else 
+		else //需要持续的区域
 		{ 
 		{ 
 			nlist.push_back(*c1);
 			nlist.push_back(*c1);
-			(*c1)->m_area->on_hover(*c1,c);
+			if((*c1)->m_area->get_frozen_count()==0)//正常情况
+			{
+				(*c1)->m_area->on_hover(*c1,c);
+			}
+			else//丢弃本次on_hover时间
+			{
+				log_warn("丢弃区域行走事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+			}
 			++c1,++a1;
 			++c1,++a1;
 		}
 		}
 	}
 	}
 
 
 	while(c1!=ce)
 	while(c1!=ce)
 	{
 	{
-		(*c1)->m_area->on_leave(*c1, c);
+		if((*c1)->m_area->get_frozen_count()==0)
+		{
+			(*c1)->m_area->on_leave(*c1, c);
+		}
+		else
+		{
+			log_warn("丢弃离开区域事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+		}
 		++c1;
 		++c1;
 	}
 	}
 
 
 	while(a1!=ae)
 	while(a1!=ae)
 	{
 	{
-		nlist.push_back(std::make_shared<area_hover>(*a1,pt));
-		(*a1)->on_enter(nlist.back(),c);
+		if((*a1)->get_frozen_count()==0)
+		{
+			nlist.push_back(std::make_shared<area_hover>(*a1,pt));
+			(*a1)->on_enter(nlist.back(),c);
+		}
+		else
+		{
+			log_warn("丢弃进入区域事件,cardid=%d,area_id=%d",c->m_id,(*a1)->id());
+		}
+
 		++a1;
 		++a1;
 	}
 	}
 
 
@@ -577,6 +656,7 @@ void area_tool::set_area_info(int mapid,double scale,int areaid,const point &pt,
 		log_info("wrong type..");
 		log_info("wrong type..");
 	}
 	}
 }
 }
+
 void area_tool::set_area_info(int mapid,int areaid,const point &pt,uint64_t t)
 void area_tool::set_area_info(int mapid,int areaid,const point &pt,uint64_t t)
 {
 {
 	auto lm = Landmark_list::instance()->get(mapid,areaid,pt);
 	auto lm = Landmark_list::instance()->get(mapid,areaid,pt);
@@ -588,3 +668,30 @@ void area_tool::set_area_info(int mapid,int areaid,const point &pt,uint64_t t)
 	m_area_info[areaid].swap(tinfo);
 	m_area_info[areaid].swap(tinfo);
 }
 }
 
 
+
+void area_tool::on_change_business(const std::shared_ptr<card_location_base>& c, const task&t)
+{
+	auto&mcb=t.body<message_change_business>();
+
+	auto i=std::lower_bound(m_hover_list.begin(),m_hover_list.end(),mcb.area_id ,[&mcb](std::shared_ptr<area_hover>&ah,int id){
+		return ah->m_area->m_id<id;
+	});
+
+	if(i==m_hover_list.end())
+		return ;
+	
+	if((*i)->m_area->m_id!=mcb.area_id)
+		return;
+	
+	log_info("调用调整的区域业务,card_id=%d,area_id=%d", c->m_id, mcb.area_id);
+	for(auto&biz:mcb.add_list)
+	{
+		biz->on_enter(*i,c,(*i)->get_business_data(biz->area_business_type()));
+	}
+
+	for(auto&biz:mcb.del_list)
+	{
+		biz->on_leave(*i,c,(*i)->get_business_data(biz->area_business_type()));
+	}
+}
+

+ 26 - 0
area.h

@@ -63,6 +63,29 @@ struct area
     }
     }
 public:
 public:
 	std::vector<area_business*> m_area_business_list;
 	std::vector<area_business*> m_area_business_list;
+	std::atomic<int> m_frozen_count;
+
+	void set_business_list(std::vector<area_business*>&&business_list)
+	{
+		m_area_business_list=business_list;	
+	}
+
+	int  get_frozen_count()
+	{
+		return m_frozen_count.load(std::memory_order_acquire);
+	}
+
+	int add_frozen_count(int deta=1)
+	{
+		return m_frozen_count.fetch_add(deta,std::memory_order_release);
+	}
+
+	int sub_frozen_count(int deta=1)
+	{
+		return add_frozen_count(-deta);
+	}
+
+	void change_business(uint32_t new_bits);
 public:
 public:
     std::vector<point> m_bound;
     std::vector<point> m_bound;
 	//数据库唯一ID
 	//数据库唯一ID
@@ -182,6 +205,7 @@ struct area_hover
 //每张卡包含一个对象
 //每张卡包含一个对象
 //在解析出数据点时,调用on_point
 //在解析出数据点时,调用on_point
 struct site;
 struct site;
+struct task;
 struct area_tool
 struct area_tool
 {
 {
 	//卡所在的所有area的列表,以id排序小->大
 	//卡所在的所有area的列表,以id排序小->大
@@ -192,11 +216,13 @@ struct area_tool
 	int m_mapid=-1;
 	int m_mapid=-1;
 	double m_scale=2.0;
 	double m_scale=2.0;
     std::shared_ptr<site> m_site=nullptr;
     std::shared_ptr<site> m_site=nullptr;
+
     void set(const std::shared_ptr<site>& s)
     void set(const std::shared_ptr<site>& s)
     {
     {
         if(m_site != s)
         if(m_site != s)
           m_site=s;
           m_site=s;
     }
     }
+	void on_change_business(const std::shared_ptr<card_location_base>& c, const task&t);
 	void on_point(const std::shared_ptr<card_location_base>& c,const point&pt);
 	void on_point(const std::shared_ptr<card_location_base>& c,const point&pt);
     void on_leave(const std::shared_ptr<card_location_base>& c);
     void on_leave(const std::shared_ptr<card_location_base>& c);
 
 

+ 27 - 10
card.cpp

@@ -18,20 +18,20 @@
 #include "mine_business.h"
 #include "mine_business.h"
 
 
 extern config_file config;
 extern config_file config;
-void card_list::init_staffer(int64_t id64)
+void card_list::init_staffer(const std::string & lszId64)
 {
 {
     std::string strategy = config.get("person.strategy","PS_1");
     std::string strategy = config.get("person.strategy","PS_1");
 
 
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
-		map=std::move(db_card::load_person(id64,strategy));
+		map=std::move(db_card::load_person(lszId64,strategy));
 
 
 	if(map.empty())
 	if(map.empty())
 	{
 	{
-		log_error("增加或修改失败,数据库中找不到: card_id=%013lld", id64);
+		log_error("增加或修改失败,数据库中找不到: card_id=%", lszId64.c_str());
 		return ;
 		return ;
 	}
 	}
 
 
-	if(-1 == id64)
+	if("" == lszId64)
 	{
 	{
 		log_info( "init_staffer. The record count=%d\n", map.size() );
 		log_info( "init_staffer. The record count=%d\n", map.size() );
 		card_list::instance()->add(map);
 		card_list::instance()->add(map);
@@ -39,6 +39,7 @@ void card_list::init_staffer(int64_t id64)
 	else
 	else
 	{
 	{
 		auto db_person=map.begin()->second;
 		auto db_person=map.begin()->second;
+        uint64_t id64 = map.begin()->first;
 		auto card_ptr = card_list::instance()->get(id64);
 		auto card_ptr = card_list::instance()->get(id64);
 		if(card_ptr)
 		if(card_ptr)
 		{
 		{
@@ -68,18 +69,18 @@ void card_list::init_staffer(int64_t id64)
 }
 }
 
 
 
 
-void card_list::init_vehicle(int64_t id64)
+void card_list::init_vehicle(const std::string & lszId64)
 {
 {
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
-		map=std::move(db_card::load_car(id64));
+		map=std::move(db_card::load_car(lszId64));
 
 
 	if(map.empty())
 	if(map.empty())
 	{
 	{
-		log_error("增加或修改失败,数据库中找不到: card_id=%013lld", id64);
+		log_error("增加或修改失败,数据库中找不到: card_id=%s", lszId64.c_str());
 		return ;
 		return ;
 	}
 	}
 
 
-	if(-1 == id64)
+	if("" == lszId64)
 	{
 	{
 		log_info( "init_vehicle. The record count=%d\n", map.size() );
 		log_info( "init_vehicle. The record count=%d\n", map.size() );
 		card_list::instance()->add(map);
 		card_list::instance()->add(map);
@@ -87,6 +88,7 @@ void card_list::init_vehicle(int64_t id64)
 	else
 	else
 	{
 	{
 		car* db_car= static_cast<car*>(map.begin()->second.get());
 		car* db_car= static_cast<car*>(map.begin()->second.get());
+        uint64_t id64 = map.begin()->first;
 		auto card_ptr = card_list::instance()->get(id64);
 		auto card_ptr = card_list::instance()->get(id64);
 		if(card_ptr)
 		if(card_ptr)
 		{
 		{
@@ -109,8 +111,8 @@ void card_list::init_vehicle(int64_t id64)
 
 
 void card_list::init_card_from_db()
 void card_list::init_card_from_db()
 {
 {
-    init_staffer(-1);
-    init_vehicle(-1);
+    init_staffer("");
+    init_vehicle("");
 }
 }
 
 
 void card_list::load_his_card_postion_from_db()
 void card_list::load_his_card_postion_from_db()
@@ -357,11 +359,26 @@ void card_list::on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_
 	c->on_message(loop,loc,is_history);
 	c->on_message(loop,loc,is_history);
 }
 }
 
 
+//获取卡数据  //标识id 人staff_id 车 vehicle_id
+std::shared_ptr<card_location_base> card_list::get_card_by_cid(int cid)
+{
+    auto t_map = m_map;
+    for(std::pair<int,std::shared_ptr<card_location_base>> me:t_map)
+    {
+        if ((int)me.second->m_cid == cid)
+        {
+            return me.second;
+        }
+    }
+    return nullptr;
+}
+
 bool card_list_visit::visit(std::shared_ptr<card_location_base> c)
 bool card_list_visit::visit(std::shared_ptr<card_location_base> c)
 {
 {
 	c->get_card(_flag);
 	c->get_card(_flag);
 	return true;	
 	return true;	
 }
 }
 
 
+
 //template<> std::shared_ptr<card_list> single_base<card_list, uint64_t, std::shared_ptr<card_location_base>>::m_instance=std::make_shared<card_list>();
 //template<> std::shared_ptr<card_list> single_base<card_list, uint64_t, std::shared_ptr<card_location_base>>::m_instance=std::make_shared<card_list>();
 
 

+ 6 - 4
card.h

@@ -14,9 +14,9 @@ struct card_list_visit:visitor<std::shared_ptr<card_location_base>>
 
 
 struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_base>>
 struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_base>>
 {
 {
-    ///id64=-1为初始化所有卡, id格式为:10000001016
-    void init_staffer(int64_t id64);
-    void init_vehicle(int64_t id64);
+    ///lszId64=为初始化所有卡, lszId64格式为:0010000001016
+    void init_staffer(const std::string & lszId64);
+    void init_vehicle(const std::string & lszId64);
     void on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_history);
     void on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_history);
     void init_card_from_db();
     void init_card_from_db();
 
 
@@ -24,6 +24,8 @@ struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_ba
     void load_his_card_postion_staff();
     void load_his_card_postion_staff();
     void load_his_card_postion_from_db();
     void load_his_card_postion_from_db();
 
 
+    //获取卡数据  //标识id 人staff_id 车 vehicle_id
+    std::shared_ptr<card_location_base> get_card_by_cid(int cid);
     ~card_list(){}
     ~card_list(){}
 };
 };
-#endif
+#endif

+ 3 - 2
card_base.cpp

@@ -56,9 +56,9 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 	m_ct = loc.m_card_ct;
 	m_ct = loc.m_card_ct;
 	m_time = loc.m_time_stamp;
 	m_time = loc.m_time_stamp;
 	auto site_ptr = sit_list::instance()->get(loc.m_site_id);
 	auto site_ptr = sit_list::instance()->get(loc.m_site_id);
-
 	if(!site_ptr)
 	if(!site_ptr)
 	{
 	{
+		log_warn("接收到分站%d的数据,CARD=%d, CT=%d,但是分站未定义",loc.m_site_id,m_id,loc.m_card_ct);
 		return;
 		return;
 	}
 	}
 
 
@@ -68,6 +68,8 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 		auto area_tool=get_area_tool();
 		auto area_tool=get_area_tool();
 		area_tool->set(site_ptr);
 		area_tool->set(site_ptr);
 		area_tool->on_point(shared_from_this(),point(1,1));
 		area_tool->on_point(shared_from_this(),point(1,1));
+
+		this->site_hover(loc.m_site_id);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -75,7 +77,6 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 		{
 		{
 			log_warn("接收到分站%d的数据,CT=%d,但是分站路径为空",site_ptr->id(),loc.m_card_ct);
 			log_warn("接收到分站%d的数据,CT=%d,但是分站路径为空",site_ptr->id(),loc.m_card_ct);
 		}
 		}
-
 		m_message_handle->on_message(loop,loc,is_history);
 		m_message_handle->on_message(loop,loc,is_history);
 	}
 	}
 }
 }

+ 48 - 45
card_message_handle.cpp

@@ -13,13 +13,12 @@
 struct one_ct_message_handle
 struct one_ct_message_handle
 {
 {
 	static loc_tool_main m_loc_tool;
 	static loc_tool_main m_loc_tool;
-	ev::timer m_min_timer,m_max_timer;
+	ev::timer *m_min_timer=nullptr,*m_max_timer=nullptr;
 	//loc_message.
 	//loc_message.
 	std::vector<loc_message> m_msg_list;
 	std::vector<loc_message> m_msg_list;
 	card_location_base*m_card;
 	card_location_base*m_card;
 	const algo_config*m_ac=nullptr;
 	const algo_config*m_ac=nullptr;
 	int  m_ct;
 	int  m_ct;
-	bool m_min_timeout=false;
 	ev::dynamic_loop * m_loop = nullptr;
 	ev::dynamic_loop * m_loop = nullptr;
 	one_ct_message_handle(card_location_base*card)
 	one_ct_message_handle(card_location_base*card)
 	{
 	{
@@ -27,52 +26,51 @@ struct one_ct_message_handle
 		m_ct=-1;
 		m_ct=-1;
 	}
 	}
 
 
-	void reset()
+	~one_ct_message_handle()
 	{
 	{
-		m_ct=-1;
-		m_min_timeout=false;
-		m_msg_list.clear();
+		delete m_min_timer;
+		delete m_max_timer;
 	}
 	}
 
 
 	void on_min_timer()
 	void on_min_timer()
 	{
 	{
-		m_min_timer.stop();
-
 		if((int)m_msg_list.size()>=m_ac->best_msg_cnt)
 		if((int)m_msg_list.size()>=m_ac->best_msg_cnt)
 		{
 		{
-			m_max_timer.stop();
+			m_max_timer->stop();
 			calc_location();
 			calc_location();
-			return;
 		}
 		}
-		m_min_timeout=true;
 	}
 	}
 
 
 	void on_max_timer()
 	void on_max_timer()
 	{
 	{
-		m_max_timer.stop();
 		calc_location();
 		calc_location();
 	}
 	}
 
 
 	void set(ev::dynamic_loop * loop)
 	void set(ev::dynamic_loop * loop)
 	{
 	{
-		m_loop = loop;
-
-		m_min_timer.set(*m_loop);
-		m_min_timer.set<one_ct_message_handle,&one_ct_message_handle::on_min_timer>(this);
-		m_max_timer.set(*m_loop);
-		m_max_timer.set<one_ct_message_handle,&one_ct_message_handle::on_max_timer>(this);
+		m_loop=loop;
+		m_min_timer=new ev::timer(*loop);
+		m_min_timer->set<one_ct_message_handle,&one_ct_message_handle::on_min_timer>(this);
+		m_max_timer=new ev::timer(*loop);
+		m_max_timer->set<one_ct_message_handle,&one_ct_message_handle::on_max_timer>(this);
 	}
 	}
 
 
 	void on_message(ev::dynamic_loop *loop,const message_locinfo&loc)
 	void on_message(ev::dynamic_loop *loop,const message_locinfo&loc)
 	{
 	{
-		if(m_loop == nullptr && loop!=nullptr)
+		if(loop==nullptr)
+			return;
+
+		if(m_loop == nullptr)
 			set(loop);
 			set(loop);
-		else if(loop == nullptr)
+
+		if(m_ct==loc.m_card_ct && m_max_timer->remaining()<0) //超过max_timer的点,抛弃
 			return;
 			return;
-		if(!m_msg_list.empty()&& m_ct!=loc.m_card_ct)
+
+		if(!m_msg_list.empty() && m_ct!=loc.m_card_ct) //ct已经回绕,重置
 		{
 		{
 			m_msg_list.clear();
 			m_msg_list.clear();
 		}
 		}
+
 		auto sitPtr = sit_list::instance()->get(loc.m_site_id);
 		auto sitPtr = sit_list::instance()->get(loc.m_site_id);
 		if(sitPtr==nullptr)
 		if(sitPtr==nullptr)
 		{
 		{
@@ -80,36 +78,32 @@ struct one_ct_message_handle
 			return;
 			return;
 		}
 		}
 		auto s=sit_list::instance()->get(loc.m_site_id);
 		auto s=sit_list::instance()->get(loc.m_site_id);
-		if(m_msg_list.empty())
+		//这里构造loc_message 保存数据
+		m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id,
+					loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc,
+					loc.m_sync_ct,loc.m_rssi));
+
+		if(m_msg_list.size()==1)//第一个点
 		{
 		{
 			m_ct=loc.m_card_ct;
 			m_ct=loc.m_card_ct;
 			m_ac=&s->config();
 			m_ac=&s->config();
-			m_min_timeout=false;
-			//这里构造loc_message 保存数据
-			m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id,
-						loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc,
-						loc.m_sync_ct,loc.m_rssi));
 
 
 			//启动本CT的最小、最大两个定时器
 			//启动本CT的最小、最大两个定时器
-			m_min_timer.start(m_ac->min_wait_time);
-			m_max_timer.start(m_ac->max_wait_time);
+			m_min_timer->start(m_ac->min_wait_time);
+			m_max_timer->start(m_ac->max_wait_time);
 			return;
 			return;
 		}
 		}
 
 
-		m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id,
-					loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc,
-					loc.m_sync_ct,loc.m_rssi));
-
-		if(m_min_timeout && (int)m_msg_list.size()>=m_ac->best_msg_cnt)
+		if(m_min_timer->remaining()<0 && (int)m_msg_list.size()>=m_ac->best_msg_cnt)
 		{
 		{
 			calc_location();
 			calc_location();
-			m_max_timer.stop();
+			m_max_timer->stop();
 		}
 		}
 	}
 	}
 
 
 	void calc_location()
 	void calc_location()
 	{
 	{
-		auto v = m_msg_list;
+		auto&v = m_msg_list;
 		if(v.empty())
 		if(v.empty())
 		{
 		{
 			return;
 			return;
@@ -122,7 +116,7 @@ struct one_ct_message_handle
 
 
 		if(!rc.empty()) m_card->on_location(std::move(rc),v);
 		if(!rc.empty()) m_card->on_location(std::move(rc),v);
 
 
-		reset();
+		m_msg_list.clear();
 		log_info("calc_location_end:card_id=%d",m_card->m_id);
 		log_info("calc_location_end:card_id=%d",m_card->m_id);
 	}
 	}
 };
 };
@@ -149,22 +143,31 @@ card_message_handle::~card_message_handle()
 
 
 void card_message_handle::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
 void card_message_handle::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
 {
 {
+#ifndef _RELEASE_
+	if(m_first_call)
+	{
+		m_first_call=false;
+		m_first_call_thread=std::this_thread::get_id();
+	}
+
+	if(m_first_call_thread!=std::this_thread::get_id())
+	{
+		log_error("%s\n","card_message_handle::on_message 无法支持多线程调用");
+		assert(false);
+	}
+#endif 
+
 	if(is_history)
 	if(is_history)
 	{
 	{
 		log_warn("%s","当前代码没有处理历史消息记录。");
 		log_warn("%s","当前代码没有处理历史消息记录。");
 		return;
 		return;
 	}
 	}
-	//
-	m_card->site_hover(loc.m_site_id);
-
+	STATUS_CARD c_status = STATUS_POWER_NOMARL;
 	if(loc.m_batty_status == 2)
 	if(loc.m_batty_status == 2)
 	{
 	{
-		m_card->do_status(STATUS_POWER_LOWER_SERIOUS);
-	}
-	else
-	{
-		m_card->do_status(STATUS_POWER_NOMARL);
+		c_status = STATUS_POWER_LOWER_SERIOUS;
 	}
 	}
+	m_card->do_status(c_status);
 
 
 	if(loc.m_callinfo & 0x80)
 	if(loc.m_callinfo & 0x80)
 	{
 	{

+ 7 - 0
card_message_handle.h

@@ -4,6 +4,8 @@
 
 
 //一张卡一个ct的所有不同天线的信息
 //一张卡一个ct的所有不同天线的信息
 
 
+#include <thread>
+
 struct card_location_base;
 struct card_location_base;
 struct one_ct_message_handle;
 struct one_ct_message_handle;
 struct message_locinfo;
 struct message_locinfo;
@@ -17,6 +19,11 @@ struct card_message_handle
 
 
 	card_message_handle(card_location_base*card);
 	card_message_handle(card_location_base*card);
 	~card_message_handle();
 	~card_message_handle();
+
+#ifndef _RELEASE_
+	bool m_first_call=true;
+	std::thread::id m_first_call_thread;
+#endif 
 	
 	
 	void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);
 	void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);
 };
 };

+ 19 - 17
card_person.cpp

@@ -15,6 +15,7 @@
 #include "mine_business.h"
 #include "mine_business.h"
 #include"common_tool.h"
 #include"common_tool.h"
 #include"db/db_tool.h"
 #include"db/db_tool.h"
+#include "forbid_staff_down_mine.h"
 
 
 person::person(const std::string &type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t level_id,uint32_t cid,int wl,const std::string &sname,const std::string &dname,int worketype_id)
 person::person(const std::string &type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t level_id,uint32_t cid,int wl,const std::string &sname,const std::string &dname,int worketype_id)
 	:card_location_base(type,cardid,needdisplay,t,deptid,level_id,cid)
 	:card_location_base(type,cardid,needdisplay,t,deptid,level_id,cid)
@@ -57,26 +58,27 @@ void person::site_hover(int sid)
 //虹膜识别入库功能	
 //虹膜识别入库功能	
 void person::IKSDK_DB(int sid)
 void person::IKSDK_DB(int sid)
 {
 {
-	auto sit_ptr = sit_list::instance()->get(sid);
-	if(nullptr == sit_ptr)
-	  return;
-	if(sit_ptr->m_reader_type_id == READER_TYPE_ID_UP)
+	printf("person::IKSDK_DB : card=%d,Sid=%d \n",m_id,sid);
+	time_t now = time(0);
+	if(now - m_iris_recognition_timeval > 5)
 	{
 	{
-		time_t now = time(0);
-		if(now - m_iris_recognition_timeval > 5)
+		if (forbid_staff_down_mine::instance()->IsForbid(m_cid,now))
 		{
 		{
-			int f=0;
-			if(event_list::instance()->get_event_card(m_id, m_type, ET_CARD_LOW_POWER_SERIOUS))
-			  f=1;
-			std::string card_id = tool_other::type_id_to_str(m_type,m_id);
-			std::string st	    = tool_time::to_str(now);
-			char nsql[256]={0};
-			const char*sql="REPLACE INTO his_att_interface (staff_id,card_id,reader_id,staff_name,dept_name,upt_time,low_power_warn) VALUES (%d,%s,%d,'%s','%s','%s',%d);";
-			snprintf(nsql,256,sql,m_cid,card_id.c_str(),sid,m_stafferName.c_str(),m_deptName.c_str(),st.c_str(),f);
-			db_tool::PushAsync(nsql);
-			logn_info(2,"%s",nsql);
-			m_iris_recognition_timeval = now;
+			log_info("Staff:%d forbid down mine",m_cid); //禁止指定人员下井
+			return;
 		}
 		}
+		int f=0;
+		if(event_list::instance()->get_event_card(m_id, m_type, ET_CARD_LOW_POWER_SERIOUS)) {
+			f = 1;
+		}
+		std::string card_id = tool_other::type_id_to_str(m_type,m_id);
+		std::string st	    = tool_time::to_str(now);
+		char nsql[256]={0};
+		const char*sql="REPLACE INTO his_att_interface (staff_id,card_id,reader_id,staff_name,dept_name,upt_time,low_power_warn) VALUES (%d,%s,%d,'%s','%s','%s',%d);";
+		snprintf(nsql,256,sql,m_cid,card_id.c_str(),sid,m_stafferName.c_str(),m_deptName.c_str(),st.c_str(),f);
+		db_tool::PushAsync(nsql);
+		logn_info(2,"%s",nsql);
+		m_iris_recognition_timeval = now;
 	}
 	}
 }
 }
 
 

+ 6 - 9
db/db_card.cpp

@@ -13,7 +13,7 @@
 extern config_file config;
 extern config_file config;
 namespace db_card
 namespace db_card
 {
 {
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(int64_t id64)
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64)
 	{
 	{
 		std::string sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, \
 		std::string sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, \
 						   ve.dept_id, ve.group_id, v.vehicle_type_id, vt.vehicle_level_id, \
 						   ve.dept_id, ve.group_id, v.vehicle_type_id, vt.vehicle_level_id, \
@@ -30,16 +30,14 @@ namespace db_card
 
 
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
 
 
-		std::string card_id_str = tool_other::to13str(id64);
-
-		if(-1 == id64)
+		if("" == lszId64)
 		{
 		{
 			sql.append(";");
 			sql.append(";");
 		}
 		}
 		else
 		else
 		{
 		{
 			sql.append(" AND ve.card_id ='");
 			sql.append(" AND ve.card_id ='");
-			sql.append(card_id_str);
+			sql.append(lszId64);
 			sql.append("';");
 			sql.append("';");
 		}
 		}
 
 
@@ -110,7 +108,7 @@ namespace db_card
 		return map;
 		return map;
 	}
 	}
 
 
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(int64_t id64,const std::string&strategy)
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&strategy)
 	{
 	{
 		std::string sql = "SELECT s.staff_id, s.card_id, c.card_type_id, s.dept_id, s.group_id, s.occupation_id, \
 		std::string sql = "SELECT s.staff_id, s.card_id, c.card_type_id, s.dept_id, s.group_id, s.occupation_id, \
 						   ol.occupation_level_id,s.worktype_id,s.need_display,s.work_line\
 						   ol.occupation_level_id,s.worktype_id,s.need_display,s.work_line\
@@ -124,15 +122,14 @@ namespace db_card
 						   WHERE s.duty_id = 0 AND c.state_id = 0";
 						   WHERE s.duty_id = 0 AND c.state_id = 0";
 
 
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
-		std::string card_id_str = tool_other::to13str(id64);
-		if(-1 == id64)
+		if("" == lszId64)
 		{
 		{
 			sql.append(";");
 			sql.append(";");
 		}
 		}
 		else
 		else
 		{
 		{
 			sql.append(" AND s.card_id = '");
 			sql.append(" AND s.card_id = '");
-			sql.append(card_id_str);
+			sql.append(lszId64);
 			sql.append("';");
 			sql.append("';");
 		}
 		}
 
 

+ 3 - 3
db/db_card.h

@@ -7,9 +7,9 @@ struct card_location_base;
 
 
 namespace db_card
 namespace db_card
 {
 {
-
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(int64_t id64,const std::string&); 
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(int64_t id64); 
+	//const std::string & lszId64 = 0010000001102
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&);
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64);
 
 
 }
 }
 
 

+ 124 - 0
forbid_staff_down_mine.cpp

@@ -0,0 +1,124 @@
+//
+// Created by Administrator on 2019/3/5.
+//
+
+#include "forbid_staff_down_mine.h"
+#include "log.h"
+#include "tool_time.h"
+#include "db_api/CDBResultSet.h"
+#include "db_api/CDBSingletonDefine.h"
+
+void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
+{
+    std::string sql = "select id,staff_id,start_time,end_time,status from rt_person_forbid_down_mine where status = 1";
+    if (id != -1)
+    {
+        m_map.clear();
+        sql += " and id = " + std::to_string(id) + ";";
+    }
+    std::string Error;
+    YADB::CDBResultSet DBRes;
+    sDBConnPool.Query(sql.c_str(),DBRes,Error);
+    int nCount = DBRes.GetRecordCount( Error );
+    if (nCount < 1)
+    {
+        log_error("增加或修改失败,数据库中找不到: sql", sql.c_str());
+        return ;
+    }
+
+    while ( DBRes.GetNextRecod(Error) )
+    {
+        int key = 0;
+        DBRes.GetField("id", key, Error);
+        unsigned int s_id = 0;
+        DBRes.GetField("staff_id", s_id, Error);
+        std::string start_time;
+        DBRes.GetField("start_time", start_time, Error);
+        std::string end_time;
+        DBRes.GetField("end_time", end_time, Error);
+        int state;
+        DBRes.GetField("status", state, Error);
+
+        if (id != -1)
+        {
+            auto s = get(id);
+            if (s != nullptr)
+            {
+                s->staff_id = s_id;
+                s->start_time = tool_time::to_time(start_time);
+                s->end_time = tool_time::to_time(end_time);
+                s->state = state;
+                continue;
+            }
+        }
+
+        std::shared_ptr<SForbidStaffInfo> s = std::make_shared<SForbidStaffInfo>();
+        s->staff_id = s_id;
+        s->start_time = tool_time::to_time(start_time);
+        s->end_time = tool_time::to_time(end_time);
+        s->state = state;
+        forbid_staff_down_mine::instance()->add(key,s);
+
+        m_forbidlist[s_id].push_back(key);
+    }
+}
+
+void forbid_staff_down_mine::del_forbid_staff(int staff_id)
+{
+    auto it = m_forbidlist.find(staff_id);
+    if (it != m_forbidlist.end()) {
+        for (auto key : it->second) {
+            forbid_staff_down_mine::instance()->remove(key);
+        }
+        m_forbidlist.erase(it);
+    }
+}
+
+void forbid_staff_down_mine::del_forbid_data(int id)
+{
+    auto s = forbid_staff_down_mine::instance()->get(id);
+    if (s != nullptr)
+    {
+        log_info(" remove Forbid Staff:%d Down mine.",s->staff_id);
+        auto it = m_forbidlist.find(s->staff_id);
+        if (it != m_forbidlist.end())
+        {
+            for (auto key : it->second)
+            {
+                if(key == id)
+                {
+                    it->second.remove(id);
+                    break;
+                }
+            }
+            if (it->second.size() == 0)
+            {
+                m_forbidlist.erase(it);
+            }
+        }
+    }
+    forbid_staff_down_mine::instance()->remove(id);
+}
+
+//是否禁止状态
+bool forbid_staff_down_mine::IsForbid(int staff_id,time_t cur_time)
+{
+    auto flist = m_forbidlist;
+    auto it = flist.find(staff_id);
+    if (it != flist.end())
+    {
+        for (auto key : it->second)
+        {
+            std::shared_ptr<SForbidStaffInfo> s = get(key);
+            if (nullptr == s) {
+                continue;
+            }
+            if (s->state == 1 && cur_time > s->start_time && cur_time < s->end_time)
+            {
+                return true;
+            }
+        }
+    }
+    //del_forbid_staff(staff_id);  //容易引起多线程问题 已过禁止时间 或者记录失效 删除
+    return false;
+}

+ 49 - 0
forbid_staff_down_mine.h

@@ -0,0 +1,49 @@
+//
+// Created by Administrator on 2019/3/5.
+// 禁止制定人员下井
+//
+
+#ifndef WORKSPACE_FORBID_STAFF_DOWN_MINE_H
+#define WORKSPACE_FORBID_STAFF_DOWN_MINE_H
+
+#include "write-copy.h"
+#include <string>
+#include <map>
+#include <list>
+
+struct SForbidStaffInfo
+{
+    int staff_id;
+    time_t start_time;
+    time_t end_time;
+    int state;          //状态 0 = 无效 1 = 有效
+    SForbidStaffInfo()
+    {
+        staff_id = 0;
+        start_time = 0;
+        end_time = 0;
+        state = 0;
+    }
+};
+
+struct forbid_staff_down_mine
+        :single_base<forbid_staff_down_mine,int,std::shared_ptr<SForbidStaffInfo>>
+{
+public:
+    // 根据数据库中的自增长id
+    void init_forbid_staff(int id = -1);
+    // 根据数据库中的自增长id
+    void del_forbid_data(int id);
+    // 根据员工ID
+    void del_forbid_staff(int staff_id);
+
+    //是否禁止状态
+    bool IsForbid(int staff_id,time_t cur_time);
+
+private:
+    typedef std::map <int ,std::list<int>> ForbidStaffList;
+    ForbidStaffList m_forbidlist;
+};
+
+
+#endif //WORKSPACE_FORBID_STAFF_DOWN_MINE_H

+ 26 - 13
main.cpp

@@ -21,6 +21,7 @@
 #include "main_test.h"
 #include "main_test.h"
 #include "ya_setting.h"
 #include "ya_setting.h"
 #include "websocket/web_connect.h"
 #include "websocket/web_connect.h"
+#include "forbid_staff_down_mine.h"
 
 
 config_file config;
 config_file config;
 void handlereader(uint32_t readerid,bool duration,uint32_t t)
 void handlereader(uint32_t readerid,bool duration,uint32_t t)
@@ -43,15 +44,7 @@ struct Init_Setting
 {
 {
     void init()
     void init()
     {
     {
-        std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
-        int32_t send_interval =config.get("service.interval_send_json_postion",1);
-        std_info("json_interval:%d",send_interval);
-        std::vector<std::string> url_list;
-        url_list.push_back(url);
-        if(!wsClientMgr_init(url_list,send_interval))
-		  exit(0);
         YADB::_DB_POOL_SETTING_ DBSetting;
         YADB::_DB_POOL_SETTING_ DBSetting;
-
         DBSetting.Host = config.get("db.host","127.0.0.1");
         DBSetting.Host = config.get("db.host","127.0.0.1");
         DBSetting.User = config.get("db.user","root");
         DBSetting.User = config.get("db.user","root");
         DBSetting.PWD = config.get("db.passwd","123456");
         DBSetting.PWD = config.get("db.passwd","123456");
@@ -59,13 +52,29 @@ struct Init_Setting
         DBSetting.CharSet = config.get("db.charset","utf8");
         DBSetting.CharSet = config.get("db.charset","utf8");
         DBSetting.TimeOut = config.get("db.conn_timeout",5);
         DBSetting.TimeOut = config.get("db.conn_timeout",5);
         DBSetting.PoolSize = config.get("db.pool_size",30);
         DBSetting.PoolSize = config.get("db.pool_size",30);
+        DBSetting.Port = config.get("db.port",3306);
         if(!_mysql_init(DBSetting))
         if(!_mysql_init(DBSetting))
-		  exit(0);
-         
+        {
+            std_info("连接DB[%s:%s] 失败,采集服务器无法启动!",DBSetting.Host.c_str(),DBSetting.User.c_str());
+            exit(0);
+        }
+
+        std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
+        int32_t send_interval =config.get("service.interval_send_json_postion",1);
+        std_info("json_interval:%d",send_interval);
+        std::vector<std::string> url_list;
+        url_list.push_back(url);
+        if(!wsClientMgr_init(url_list,send_interval))
+        {
+            std_info("连接webServer[%s] 失败,采集服务器无法启动!",url.c_str());
+            exit(0);
+        }
+
 		CYaSetting::Init_sys_setting();
 		CYaSetting::Init_sys_setting();
         sit_list::instance()->load_from_db();
         sit_list::instance()->load_from_db();
         card_list::instance()->init_card_from_db();
         card_list::instance()->init_card_from_db();
         area_list::instance()->init_from_db();
         area_list::instance()->init_from_db();
+        forbid_staff_down_mine::instance()->init_forbid_staff();
         //point pt(3348,100);
         //point pt(3348,100);
         //int id = area_list::instance()->get_area(pt)->id();
         //int id = area_list::instance()->get_area(pt)->id();
         //std_info("test area:%d",id);
         //std_info("test area:%d",id);
@@ -86,19 +95,22 @@ struct Init_Setting
         dp.CharSet=DBSetting.CharSet ;
         dp.CharSet=DBSetting.CharSet ;
         dp.TimeOut=DBSetting.TimeOut;
         dp.TimeOut=DBSetting.TimeOut;
         dp.PoolSize=DBSetting.PoolSize;
         dp.PoolSize=DBSetting.PoolSize;
-	init_three_rates(dp);
+		init_three_rates(dp);
 
 
-        printf("Init_Setting::init  Success. \n" );
+        log_info("Init_Setting::init  Success. \n" );
     }
     }
+
 	void init_three_rates(const db_para& dbs)
 	void init_three_rates(const db_para& dbs)
 	{
 	{
-		std_info("three_rates ...................");
+		log_info("init three_rates ...................");
 		init_para ip;
 		init_para ip;
 		ip.send_pt = handlereader;
 		ip.send_pt = handlereader;
 		ip.driving_face_alarm = Handle_ThreeRates_Event_Callback;
 		ip.driving_face_alarm = Handle_ThreeRates_Event_Callback;
 		three_rates::get_instance()->init(ip,dbs);
 		three_rates::get_instance()->init(ip,dbs);
 		three_rates::get_instance()->start();
 		three_rates::get_instance()->start();
+        std_info("加载三率模块成功");
 	}
 	}
+
     bool _mysql_init(YADB::_DB_POOL_SETTING_ &dps)
     bool _mysql_init(YADB::_DB_POOL_SETTING_ &dps)
     {
     {
         std::string szError = "";
         std::string szError = "";
@@ -110,6 +122,7 @@ struct Init_Setting
             std_error("数据库线程池创建失败,Err=%s", szError.c_str());
             std_error("数据库线程池创建失败,Err=%s", szError.c_str());
 			flag = false;
 			flag = false;
         }
         }
+        std_info("数据库线程池创建成功");
 		return flag;
 		return flag;
     }
     }
 
 

+ 84 - 43
module_service/module_meta_date_changed.cpp

@@ -10,7 +10,11 @@
 #include"ant.h"
 #include"ant.h"
 #include"card.h"
 #include"card.h"
 #include"area.h"
 #include"area.h"
-
+#include "forbid_staff_down_mine.h"
+#include <boost/format.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string.hpp>
 
 
 ///基础数据
 ///基础数据
 void module_meta_date_changed::accept(sio::message::ptr const& data)
 void module_meta_date_changed::accept(sio::message::ptr const& data)
@@ -25,11 +29,13 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
 
 
     int64_t id=-1;
     int64_t id=-1;
     tool_map::try_get_value(id, JSON_KEY_ID, data);
     tool_map::try_get_value(id, JSON_KEY_ID, data);
+    std::string szParam = "0";
+    tool_map::try_get_value(szParam,JSON_KEY_ID,data);
 
 
     std::string op_type="";
     std::string op_type="";
     tool_map::try_get_value(op_type, JSON_KEY_OP_TYPE, data);
     tool_map::try_get_value(op_type, JSON_KEY_OP_TYPE, data);
 
 
-    if(-1 != id && !op_type.empty())
+    if((-1 != id || szParam != "0") && !op_type.empty())
     {
     {
         EDIT_TYPE_ID edit_type_id;
         EDIT_TYPE_ID edit_type_id;
         if(!try_get_edit_type_id(op_type, edit_type_id))
         if(!try_get_edit_type_id(op_type, edit_type_id))
@@ -37,20 +43,20 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
             log_error("web发来的数据: 基础数据op_type字段错误:op_type=%s", op_type.c_str());
             log_error("web发来的数据: 基础数据op_type字段错误:op_type=%s", op_type.c_str());
             return;
             return;
         }
         }
-
-		log_info("基础数据 receive meta_data_changed: %s, id=%d, op_type=%d", name.c_str(), id, edit_type_id);
+		log_info("基础数据 receive meta_data_changed: %s, id=%d-%s, op_type=%d"
+		        , name.c_str(), id,szParam.c_str() , edit_type_id);
 
 
         if(JSON_KEY_NAME_VEHICLE == name || JSON_KEY_NAME_VEHICLE_EXTEND == name)
         if(JSON_KEY_NAME_VEHICLE == name || JSON_KEY_NAME_VEHICLE_EXTEND == name)
         {
         {
-            deal_call_edit_vehicle(id, edit_type_id);
+            deal_call_edit_vehicle_or_staff(szParam, edit_type_id);
         }
         }
         else if(JSON_KEY_NAME_STAFF == name || JSON_KEY_NAME_STAFF_EXTEND == name)
         else if(JSON_KEY_NAME_STAFF == name || JSON_KEY_NAME_STAFF_EXTEND == name)
         {
         {
-            deal_call_edit_staff(id, edit_type_id);
+            deal_call_edit_vehicle_or_staff(szParam, edit_type_id);
         }
         }
         else if(JSON_KEY_NAME_CARD == name)
         else if(JSON_KEY_NAME_CARD == name)
         {
         {
-            deal_call_edit_card(id, edit_type_id);
+            deal_call_edit_card(szParam, edit_type_id);
         }
         }
         else if(JSON_KEY_NAME_AREA == name)
         else if(JSON_KEY_NAME_AREA == name)
         {
         {
@@ -80,6 +86,10 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
         {
         {
             deal_call_edit_lights_group(id,edit_type_id);///待实现
             deal_call_edit_lights_group(id,edit_type_id);///待实现
         }
         }
+        else if (JSON_KEY_NAME_FORBID_PERSON_DOWN_MINE == name)
+        {
+            deal_call_edit_forbid_person_down_mine(id,edit_type_id);
+        }
         else
         else
         {
         {
             log_error("web发来的数据: 基础数据name字段错误:name=%s", name.c_str());
             log_error("web发来的数据: 基础数据name字段错误:name=%s", name.c_str());
@@ -132,48 +142,61 @@ void module_meta_date_changed::clear_card(std::shared_ptr<card_location_base> ca
         //        }
         //        }
     }
     }
 }
 }
-
-
-void module_meta_date_changed::deal_call_edit_vehicle(int64_t id64, EDIT_TYPE_ID edit_type_id)
+/*
+ * 修改车及卡的数据
+ * id64 = ;员工ID或者车ID;卡ID=101;0010000001198  分号间隔
+ */
+void module_meta_date_changed::deal_call_edit_vehicle_or_staff(const std::string & id64, EDIT_TYPE_ID edit_type_id)
 {
 {
-    if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
-    {
-        card_list::instance()->init_vehicle(id64);
-    }
-    else if(ET_DELETE == edit_type_id)
+    std::vector<std::string> vecSegTag;
+    boost::split(vecSegTag, id64, boost::is_any_of(";"));
+    if (vecSegTag.size() == 1)  //数据发生错误
     {
     {
-        auto str = tool_other::to13str(id64);
-
-        remove_card(tool_other::id64_to_id(str), tool_other::id64_to_type(str));
+        log_errno("Web Send Data Error!(%s)", id64.c_str());
+        return;
     }
     }
-}
-
-void module_meta_date_changed::deal_call_edit_staff(int64_t id64, EDIT_TYPE_ID edit_type_id)
-{
+    std::string lsz_card_id = vecSegTag[1];
+    int cid = std::stoi(vecSegTag[0].c_str());
     if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
     if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
     {
     {
-        card_list::instance()->init_staffer(id64);
+        if (ET_UPDATE == edit_type_id)
+        {
+            auto c = card_list::instance()->get_card_by_cid(cid);
+            if (nullptr != c && tool_other::type_id_to_str(c->m_type,c->m_id) != lsz_card_id)
+            {
+                //如果修改了卡号,则删除原来的卡的数据
+                remove_card(c);
+            }
+        }
+        int c_type = tool_other::id64_to_type(lsz_card_id);
+        if (tool_other::is_vehicle(c_type))
+        {
+            card_list::instance()->init_vehicle(lsz_card_id);
+        }
+        else if (tool_other::is_person(c_type))
+        {
+            card_list::instance()->init_staffer(lsz_card_id);
+        }
     }
     }
-    else if(ET_DELETE == edit_type_id)
+    else
     {
     {
-        auto str = tool_other::to13str(id64);
-
-        remove_card(tool_other::id64_to_id(str), tool_other::id64_to_type(str));
+        remove_card(tool_other::id64_to_id(lsz_card_id), tool_other::id64_to_type(lsz_card_id));
     }
     }
 }
 }
 
 
-void module_meta_date_changed::deal_call_edit_card(int64_t id64, EDIT_TYPE_ID edit_type_id)
+void module_meta_date_changed::deal_call_edit_card(std::string & id64, EDIT_TYPE_ID edit_type_id)
 {
 {
-    std::string card_id64_str = tool_other::to13str(static_cast<uint64_t>(id64));
+    std::string card_id64_str = tool_other::to13str(id64);
     int type = tool_other::id64_to_type(card_id64_str);
     int type = tool_other::id64_to_type(card_id64_str);
-
-    if(tool_other::is_person(type))
-    {
-        deal_call_edit_staff(id64, edit_type_id);
-    }
-    else if(tool_other::is_vehicle(type))
+    if(tool_other::is_person(type) || tool_other::is_vehicle(type))
     {
     {
-        deal_call_edit_vehicle(id64, edit_type_id);
+        auto c = card_list::instance()->get(tool_other::card_id_to_u64(card_id64_str));
+        if (nullptr == c) {
+            log_info("web edit card:%s Not bind staff or vehicle. editType:%d", card_id64_str.c_str(), edit_type_id);
+            return ;
+        }
+        std::string lsz = std::to_string(c->m_cid) + ";" + card_id64_str;
+        deal_call_edit_vehicle_or_staff(lsz,edit_type_id);
     }
     }
     else
     else
     {
     {
@@ -300,21 +323,40 @@ void module_meta_date_changed::deal_call_edit_lights_group(int id, EDIT_TYPE_ID
     }
     }
 }
 }
 
 
+// 禁止指定人员下井 id = (rt_person_forbid_down_mine)数据库中自增长ID
+void module_meta_date_changed::deal_call_edit_forbid_person_down_mine(int id,EDIT_TYPE_ID edit_type_id)
+{
+    if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
+    {
+        forbid_staff_down_mine::instance()->init_forbid_staff(id);
+    }
+    else if(ET_DELETE == edit_type_id)
+    {
+        forbid_staff_down_mine::instance()->del_forbid_data(id);
+    }
+}
+
 void module_meta_date_changed::init_setting()
 void module_meta_date_changed::init_setting()
 {
 {
     //pRes = getMysqlRes("select setting_id, name, type, value from dat_setting;");
     //pRes = getMysqlRes("select setting_id, name, type, value from dat_setting;");
 }
 }
 
 
-void module_meta_date_changed::remove_card(uint32_t id, int32_t type)
-{
+void module_meta_date_changed::remove_card(uint32_t id, int32_t type) {
     uint64_t card_id = tool_other::type_id_to_u64(type, id);
     uint64_t card_id = tool_other::type_id_to_u64(type, id);
     auto card_ptr = card_list::instance()->get(card_id);
     auto card_ptr = card_list::instance()->get(card_id);
-    if(!card_ptr)
-    {
+    if (!card_ptr) {
         log_error("基础数据, 在全局列表中删除卡,全局列表中已经不存在此卡, id=%d, type=%d", id, type);
         log_error("基础数据, 在全局列表中删除卡,全局列表中已经不存在此卡, id=%d, type=%d", id, type);
         return;
         return;
     }
     }
-
+    remove_card(card_ptr);
+}
+void module_meta_date_changed::remove_card(std::shared_ptr<card_location_base> card_ptr)
+{
+    if (!card_ptr)
+    {
+        return;
+    }
+    log_info("基础数据, 在全局列表中删除卡成功, id=%d, type=%d",card_ptr->m_type, card_ptr->m_id);
     //    auto area_hover_ptr = card_ptr->get_area_hover();
     //    auto area_hover_ptr = card_ptr->get_area_hover();
     //    if(area_hover_ptr && 0!=area_hover_ptr->id() && 0!=area_hover_ptr->mapid())
     //    if(area_hover_ptr && 0!=area_hover_ptr->id() && 0!=area_hover_ptr->mapid())
     //    {
     //    {
@@ -331,11 +373,10 @@ void module_meta_date_changed::remove_card(uint32_t id, int32_t type)
 
 
     //        module_meta_date_changed::clear_card(card_ptr);
     //        module_meta_date_changed::clear_card(card_ptr);
     //    }
     //    }
-
     module_meta_date_changed::clear_card(card_ptr);
     module_meta_date_changed::clear_card(card_ptr);
     // 避免状态重置
     // 避免状态重置
+    uint64_t card_id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
     card_list::instance()->remove(card_id);
     card_list::instance()->remove(card_id);
-    log_info("基础数据, 在全局列表中删除卡成功, id=%d, type=%d", id, type);
 }
 }
 
 
 bool module_meta_date_changed::try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id)
 bool module_meta_date_changed::try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id)

+ 10 - 6
module_service/module_meta_date_changed.h

@@ -43,14 +43,14 @@ public:
     static void clear_card(std::shared_ptr<card_location_base> card_ptr);
     static void clear_card(std::shared_ptr<card_location_base> card_ptr);
 
 
 private:
 private:
-    ///id64格式为:10000001016
-    void deal_call_edit_vehicle(int64_t id64, EDIT_TYPE_ID edit_type_id);
-
-    ///id64格式为:10000001016
-    void deal_call_edit_staff(int64_t id64, EDIT_TYPE_ID edit_type_id);
+    /*
+     * 修改车及卡的数据
+     * id64 = ;员工ID或者车ID;卡ID=101;0010000001198  分号间隔
+     */
+    void deal_call_edit_vehicle_or_staff(const std::string & id64, EDIT_TYPE_ID edit_type_id);
 
 
     ///id64格式为10000006666
     ///id64格式为10000006666
-    void deal_call_edit_card(int64_t id64, EDIT_TYPE_ID edit_type_id);
+    void deal_call_edit_card(std::string & id64, EDIT_TYPE_ID edit_type_id);
 
 
     void deal_call_edit_reader(int id, EDIT_TYPE_ID edit_type_id);
     void deal_call_edit_reader(int id, EDIT_TYPE_ID edit_type_id);
 
 
@@ -69,10 +69,14 @@ private:
     ///待实现
     ///待实现
     void deal_call_edit_lights_group(int id,EDIT_TYPE_ID edit_type_id);
     void deal_call_edit_lights_group(int id,EDIT_TYPE_ID edit_type_id);
 
 
+    // 禁止指定人员下井
+    void deal_call_edit_forbid_person_down_mine(int id,EDIT_TYPE_ID edit_type_id);
+
     ///待实现
     ///待实现
     void init_setting();
     void init_setting();
 
 
     void remove_card(uint32_t id, int32_t type);
     void remove_card(uint32_t id, int32_t type);
+    void remove_card(std::shared_ptr<card_location_base> card_ptr);
 
 
     bool try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id);
     bool try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id);
 
 

+ 17 - 5
net-service.cpp

@@ -48,6 +48,7 @@ void net_service::on_timer()
 
 
 void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t len)
 void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t len)
 {
 {
+	bool message_handled=true;
 	try
 	try
 	{
 	{
 		zistream is(data,len-2);
 		zistream is(data,len-2);
@@ -57,13 +58,19 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 		{
 		{
 			case CHAR_LOCATEDATA_TOF_EXTEND://tof-扩展
 			case CHAR_LOCATEDATA_TOF_EXTEND://tof-扩展
 				{
 				{
+					if(!clt->check_timestamp(data+10))
+					{
+						logn_error(1,"分站数据时间戳错误:%s",clt->name().c_str());
+						break;
+					}
+
 					uint32_t site_id;
 					uint32_t site_id;
 					uint8_t  power;
 					uint8_t  power;
 					is>>site_id>>skip(11)>>power;
 					is>>site_id>>skip(11)>>power;
 					auto site_ptr = sit_list::instance()->get(static_cast<int32_t>(site_id));
 					auto site_ptr = sit_list::instance()->get(static_cast<int32_t>(site_id));
 					if(!site_ptr)
 					if(!site_ptr)
 					{
 					{
-						log_error("在全局分站列表中找不到分站:分站id=%d", site_id);
+						logn_error(1,"在全局分站列表中找不到分站:%d", site_id);
 						break;
 						break;
 					}
 					}
 					site_ptr->set_client(clt);
 					site_ptr->set_client(clt);
@@ -119,17 +126,22 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 				break;
 				break;
 			case CHAR_LOCATEDATAHIS_TOF_EXTEND://tof his
 			case CHAR_LOCATEDATAHIS_TOF_EXTEND://tof his
 			case CHAR_LOCATEDATAHIS_TDOA_EXTEND://tdoa his
 			case CHAR_LOCATEDATAHIS_TDOA_EXTEND://tdoa his
-				break;
 			case CHAR_CTRL_READER_CMD://ctrl site message
 			case CHAR_CTRL_READER_CMD://ctrl site message
-				break;
 			case CHAR_ADHOC://自组网数据
 			case CHAR_ADHOC://自组网数据
-				break;
+			default:
+				message_handled=false;
 		}
 		}
+
 	}
 	}
 	catch(const std::exception&e)
 	catch(const std::exception&e)
 	{
 	{
-		log_error("parse site message error,will close the connection:%s",clt->name().c_str());
+		logn_error(1,"分站数据处理失败,将关闭分站连接:%s",clt->name().c_str());
 		clt->close();
 		clt->close();
 	}
 	}
+
+	if(!message_handled)
+	{
+		logn_error(1,"分站数据未被处理,site=%s",clt->name().c_str());
+	}
 }
 }
 
 

+ 16 - 1
test.cpp

@@ -227,6 +227,19 @@ struct web_client_http:ev::io
 		return -1;
 		return -1;
 	}
 	}
 
 
+	int request(const char*what)
+	{
+		int len=strlen(what);
+
+        if(len!=zio::writev(m_fd, what, len))
+		{
+			close();
+			return -1;
+		}
+
+		return 0;
+	}
+
 	int read_until(const char*what,int timeout=10*1000)
 	int read_until(const char*what,int timeout=10*1000)
 	{
 	{
 		int rc=0;
 		int rc=0;
@@ -332,18 +345,20 @@ int main()
 {
 {
 	unsigned char buf[32];
 	unsigned char buf[32];
 	const char*s64="puVOuWb7rel6z2AVZBKnfw==";
 	const char*s64="puVOuWb7rel6z2AVZBKnfw==";
+	const char*login="{\"cmd\":\"login\",\"data\":{\"user_name\":\"zzj\",\"user_pass\":\"111111\"}}\n";
 
 
 	int blen=32;
 	int blen=32;
 	base64::decode((char*)s64,strlen(s64),buf,blen);
 	base64::decode((char*)s64,strlen(s64),buf,blen);
 
 
 	web_client_http client;
 	web_client_http client;
-	client.connect_ws("60.220.238.150",8086);
+	client.connect_ws("127.0.0.1",9001);
 
 
 	for(;;)
 	for(;;)
 	{
 	{
 		while(client.ws_parse()==0)
 		while(client.ws_parse()==0)
 			client.ws_reset();
 			client.ws_reset();
 
 
+		client.request(login);
 		client.read_until("\n");
 		client.read_until("\n");
 	}
 	}
 
 

+ 3 - 0
websocket/constdef.h

@@ -71,6 +71,9 @@
 #define JSON_KEY_NAME_DRIVINGFACE "drivingface_vehicle"
 #define JSON_KEY_NAME_DRIVINGFACE "drivingface_vehicle"
 #define JSON_KEY_NAME_DRIVINGFACE_WARNING_POINT "dat_drivingface_warning_point"
 #define JSON_KEY_NAME_DRIVINGFACE_WARNING_POINT "dat_drivingface_warning_point"
 #define JSON_KEY_NAME_HAND_UP "dat_handup_vehicle"
 #define JSON_KEY_NAME_HAND_UP "dat_handup_vehicle"
+//禁止指定人员下井
+#define JSON_KEY_NAME_FORBID_PERSON_DOWN_MINE "rt_person_forbid_down_mine"
+
 
 
 #define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
 #define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
 #define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"
 #define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"

+ 56 - 7
worker.cpp

@@ -14,6 +14,7 @@
 #include "card_base.h"
 #include "card_base.h"
 #include "card.h"
 #include "card.h"
 #include "zloop.h"
 #include "zloop.h"
+#include "area.h"
 
 
 struct hash_thread
 struct hash_thread
 {
 {
@@ -65,11 +66,10 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 		for(task*t:task_list)
 		for(task*t:task_list)
 		{
 		{
 			do_task(*t);
 			do_task(*t);
-			free(t);
 		}
 		}
 	}
 	}
 
 
-	void on_timeout()
+	void update_local_cards()
 	{
 	{
 		int version=card_list::instance()->version();
 		int version=card_list::instance()->version();
 		if(m_card_list_version!=version)
 		if(m_card_list_version!=version)
@@ -77,7 +77,11 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 			m_card_list_version=version;
 			m_card_list_version=version;
 			init_local_card_list();
 			init_local_card_list();
 		}
 		}
+	}
 
 
+	void on_timeout()
+	{
+		update_local_cards();
 		for(auto&c:m_local_card_list)
 		for(auto&c:m_local_card_list)
 		{
 		{
 			c->on_timer();
 			c->on_timer();
@@ -100,7 +104,7 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 		card_list::instance()->accept(*this);
 		card_list::instance()->accept(*this);
 	}
 	}
 
 
-	void do_task(const task&t)
+	void do_task(task&t)
 	{
 	{
 		switch(t.m_cmd_code)
 		switch(t.m_cmd_code)
 		{
 		{
@@ -108,6 +112,7 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 			case 0x863b://tdoa
 			case 0x863b://tdoa
 				log_info("card loc message%04X",t.m_cmd_code);
 				log_info("card loc message%04X",t.m_cmd_code);
 				card_list::instance()->on_message(this,t.body<message_locinfo>(),false);
 				card_list::instance()->on_message(this,t.body<message_locinfo>(),false);
+				free(&t);
 
 
 				//card_message::on_loc_message(this,t.m_param1);
 				//card_message::on_loc_message(this,t.m_param1);
 			break;
 			break;
@@ -116,11 +121,36 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 				log_info("site history message%04X",t.m_cmd_code);
 				log_info("site history message%04X",t.m_cmd_code);
 					card_list::instance()->on_message(this,t.body<message_locinfo>(),true);
 					card_list::instance()->on_message(this,t.body<message_locinfo>(),true);
 				//site_message::on_sync(this,t.m_param1);
 				//site_message::on_sync(this,t.m_param1);
+				free(&t);
 			break;
 			break;
 
 
 			case 0x804c://ctrl site message
 			case 0x804c://ctrl site message
 				log_info("ctrl site message%04X",t.m_cmd_code);
 				log_info("ctrl site message%04X",t.m_cmd_code);
+				free(&t);
 			break;
 			break;
+
+			case 0x10001://区域业务类型修改
+			{
+				update_local_cards();
+				for(auto&c:m_local_card_list)
+				{
+					c->get_area_tool()->on_change_business(c,t);
+				}
+
+				auto&mcb=t.body<message_change_business>();
+				std::shared_ptr<area> a=area_list::instance()->get(mcb.area_id);
+
+				if(a && a->sub_frozen_count()==2)
+				{
+					a->set_business_list(std::move(mcb.new_list));
+					a->sub_frozen_count();
+				}
+
+				if(mcb.ref_count.fetch_sub(1)==1)
+				{
+					free(&t);
+				}
+			}
 		}
 		}
 	}
 	}
 
 
@@ -157,11 +187,27 @@ struct worker_impl:worker
 		return *m_threads[g_hash.hash_code(i)];
 		return *m_threads[g_hash.hash_code(i)];
 	}
 	}
 
 
+	virtual int  num_thread()
+	{
+		return std::thread::hardware_concurrency();
+	}
+
+	bool running()
+	{
+		return m_init_flag.load()==0;
+	}
+
 	virtual void request(task*t)
 	virtual void request(task*t)
 	{
 	{
 		hash(t->m_hash_id).async_request(t);
 		hash(t->m_hash_id).async_request(t);
 	}
 	}
 
 
+	virtual void broadcast(task*tk) 
+	{
+		for(auto&thr:m_threads)
+			thr->async_request(tk);
+	}
+
 	void init(int num_thread)
 	void init(int num_thread)
 	{
 	{
 		int exp=-2;
 		int exp=-2;
@@ -184,11 +230,14 @@ struct worker_impl:worker
 worker_impl _worker_impl;
 worker_impl _worker_impl;
 worker*worker::instance()
 worker*worker::instance()
 {
 {
-	int num_thread=std::thread::hardware_concurrency()*2;
+	int num_thread=_worker_impl.num_thread();
+	if(!_worker_impl.running())
+	{
+		log_info("worker thread count=%d",num_thread);
+		g_hash.set_num_thread(num_thread);
+		_worker_impl.init(num_thread);
+	}
 
 
-	log_info("worker thread count=%d",num_thread);
-	g_hash.set_num_thread(num_thread);
-	_worker_impl.init(num_thread);
 	return &_worker_impl;
 	return &_worker_impl;
 }
 }
 
 

+ 16 - 0
worker.h

@@ -36,10 +36,26 @@ struct task
 	}
 	}
 };
 };
 
 
+struct area_business;
+struct message_change_business
+{
+	int area_id;
+	std::atomic<int> ref_count;
+	std::vector<area_business*> del_list,add_list,new_list;
+};
+
 struct worker
 struct worker
 {
 {
 	virtual void stop()=0;
 	virtual void stop()=0;
 	virtual void request(task*tk)=0;
 	virtual void request(task*tk)=0;
+	virtual void broadcast(task*tk) 
+	{
+	}
+
+	virtual int  num_thread()
+	{
+		return 1;
+	}
 
 
 	static worker*instance();
 	static worker*instance();
 };
 };

+ 76 - 18
znet.cpp

@@ -1,6 +1,7 @@
 #include <log.h>
 #include <log.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <signal.h>
 #include <signal.h>
+#include <sys/time.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <list>
 #include <list>
 #include <vector>
 #include <vector>
@@ -10,6 +11,7 @@
 #include <atomic>
 #include <atomic>
 #include <algorithm>
 #include <algorithm>
 #include <fstream>
 #include <fstream>
+#include <time.h>
 
 
 #include <zio.h>
 #include <zio.h>
 #include <znet.h>
 #include <znet.h>
@@ -21,12 +23,15 @@
 #include "crc.h"
 #include "crc.h"
 
 
 extern config_file config;
 extern config_file config;
+int site_sync=config.get("site_sync",0);//分站时间同步,考虑到双IP双机情况,缺省关闭
+int site_sync_freq=config.get("site_sync.freq",60);//分站时间同步间隔
 struct client_ex:client
 struct client_ex:client
 {
 {
 	virtual void on_notify()=0;
 	virtual void on_notify()=0;
 	virtual void close_impl()=0;
 	virtual void close_impl()=0;
 };
 };
 
 
+
 struct io_context: zloop<std::shared_ptr<client>> ,service_handle
 struct io_context: zloop<std::shared_ptr<client>> ,service_handle
 {
 {
 private:
 private:
@@ -41,7 +46,7 @@ public:
 	{
 	{
 		m_thread_clts.reserve(2048);
 		m_thread_clts.reserve(2048);
 		m_timer.set<io_context,&io_context::on_timer>(this);
 		m_timer.set<io_context,&io_context::on_timer>(this);
-		m_timer.start(20,1);
+		m_timer.start(0,1);
 	}
 	}
 
 
 	virtual ~io_context()
 	virtual ~io_context()
@@ -188,6 +193,7 @@ struct sock_client:fd_io,client_ex
 	int   m_max_package_size{4096};
 	int   m_max_package_size{4096};
 
 
 	ev::timer  m_recv_timer;
 	ev::timer  m_recv_timer;
+	ev::timer  m_sync_timer;
 //	ev::timer  m_send_timer;
 //	ev::timer  m_send_timer;
 	
 	
 	std::mutex m_mutex;
 	std::mutex m_mutex;
@@ -196,18 +202,26 @@ struct sock_client:fd_io,client_ex
 	size_t m_opos=0;
 	size_t m_opos=0;
 	bool   m_can_write{false};
 	bool   m_can_write{false};
 
 
+	char m_timestamp[8];
+
 	sock_client(io_context&ic,const char*name,int fd,int recv_time_out,int max_package_size)
 	sock_client(io_context&ic,const char*name,int fd,int recv_time_out,int max_package_size)
 		:fd_io(ic,fd,EV_READ|EV_WRITE)
 		:fd_io(ic,fd,EV_READ|EV_WRITE)
 		,m_ic(ic)
 		,m_ic(ic)
 		,m_name(name)
 		,m_name(name)
 		,m_recv_timer(ic)
 		,m_recv_timer(ic)
+		,m_sync_timer(ic)
 	{ 
 	{ 
 		m_max_package_size=max_package_size;
 		m_max_package_size=max_package_size;
 
 
 //		m_recv_timer.set(ic);
 //		m_recv_timer.set(ic);
-		m_recv_timer.set(recv_time_out,0);
 		m_recv_timer.set<sock_client,&sock_client::on_recv_timeout>(this);
 		m_recv_timer.set<sock_client,&sock_client::on_recv_timeout>(this);
-		m_recv_timer.start();
+		m_recv_timer.start(recv_time_out,0);
+
+		m_sync_timer.set<sock_client,&sock_client::on_sync_timeout>(this);
+		if(site_sync)
+		{
+			m_sync_timer.start(0,site_sync_freq);
+		}
 
 
 //		m_send_timer.set(ic);
 //		m_send_timer.set(ic);
 //		m_send_timer.set(5,0);
 //		m_send_timer.set(5,0);
@@ -215,6 +229,7 @@ struct sock_client:fd_io,client_ex
 //		m_send_timer.start();
 //		m_send_timer.start();
 
 
 		m_b=(char*)malloc(m_size);
 		m_b=(char*)malloc(m_size);
+		m_timestamp[0]=0;
 	}
 	}
 
 
 	~sock_client()
 	~sock_client()
@@ -222,6 +237,27 @@ struct sock_client:fd_io,client_ex
 		free(m_b);
 		free(m_b);
 	}
 	}
 
 
+
+	bool check_timestamp(const char*time)
+	{
+		//秒、分、时、天、周、月、年, 脑残的设计
+		
+		char buf[6];
+		buf[0]=time[6];
+		buf[1]=time[5];
+		buf[2]=time[3];
+		buf[3]=time[2];
+		buf[4]=time[1];
+		buf[5]=time[0];
+
+		if(memcmp(m_timestamp,buf,6)<=0)
+		{
+			memcpy(m_timestamp,buf,6);
+			return true;
+		}
+		return false;
+	}
+
 	int type()
 	int type()
 	{
 	{
 		return m_type;
 		return m_type;
@@ -242,6 +278,38 @@ struct sock_client:fd_io,client_ex
 		m_ic.async_request(shared_from_this());
 		m_ic.async_request(shared_from_this());
 	}
 	}
 
 
+	void on_sync_timeout()
+	{
+//	从第一个字节开始,分别表示毫秒(2字节)、秒、分、时、天、月、年
+		char buf[14]={0,12,0x78,0x3b};
+
+		struct timeval tv;
+		gettimeofday(&tv,0);
+
+		struct tm buff={0};
+		const struct tm*t=localtime_r(&tv.tv_sec,&buff);
+
+		int p=4;
+		buf[p++]=(tv.tv_usec/1000)>>8;
+		buf[p++]=(tv.tv_usec/1000)&0xff;
+
+		//为防止分站重启时发送上来过大的时间
+		m_timestamp[5]=buf[p++]=t->tm_sec;
+		m_timestamp[4]=buf[p++]=t->tm_min;
+		m_timestamp[3]=buf[p++]=t->tm_hour;
+		m_timestamp[2]=buf[p++]=t->tm_mday;
+		m_timestamp[1]=buf[p++]=t->tm_mon;
+		m_timestamp[0]=buf[p++]=t->tm_year;
+
+		uint16_t ccrc=do_crc((unsigned char*)buf+2,10);
+
+		buf[p++]=ccrc>>8;
+		buf[p++]=ccrc&0xff;
+
+		std::vector<char> tmp(buf,buf+14);
+		send(std::move(tmp));
+	}
+
 	void on_send_timeout()
 	void on_send_timeout()
 	{
 	{
 		m_ic.on_send_timeout(shared_from_this());
 		m_ic.on_send_timeout(shared_from_this());
@@ -293,11 +361,11 @@ struct sock_client:fd_io,client_ex
 
 
 			if(rc==0)
 			if(rc==0)
 			{
 			{
-				log_info("socket %d(%s) close by remote",m_fd,m_name.c_str());
+				logn_info(1,"socket %d(%s) close by remote",m_fd,m_name.c_str());
 			}
 			}
 			else if(rc==-1)
 			else if(rc==-1)
 			{
 			{
-				log_errno("hava a error on socket %d(%s)",m_fd,m_name.c_str());
+				logn_errno(1,"hava a error on socket %d(%s)",m_fd,m_name.c_str());
 			}
 			}
 			return -1;
 			return -1;
 		}
 		}
@@ -341,7 +409,7 @@ struct sock_client:fd_io,client_ex
 			}
 			}
 			else
 			else
 			{
 			{
-				log_errno("check_crc_error,socket close... site=%s.",m_name.c_str());
+				logn_error(1,"check_crc_error,close socket. site=%s.",m_name.c_str());
 				return -1;
 				return -1;
 			}
 			}
 
 
@@ -394,7 +462,7 @@ struct sock_client:fd_io,client_ex
 			}
 			}
 			else
 			else
 			{
 			{
-				log_errno("zio::write(%d,ptr,%d)",m_fd,m_obuf.size()-m_opos);
+				logn_errno(1,"zio::write(%d,ptr,%d)",m_fd,m_obuf.size()-m_opos);
 				return -1;
 				return -1;
 			}
 			}
 		}
 		}
@@ -412,7 +480,7 @@ struct sock_client:fd_io,client_ex
 	{
 	{
 		if(flag & EV_WRITE)
 		if(flag & EV_WRITE)
 		{
 		{
-			log_debug("socket %d(%s) can write,flag=%d." ,m_fd,m_name.c_str(),flag);
+			logn_debug(1,"socket %d(%s) can write,flag=%d." ,m_fd,m_name.c_str(),flag);
 			m_can_write=true;
 			m_can_write=true;
 //			m_send_timer.stop();
 //			m_send_timer.stop();
 			if(io_write()<0)
 			if(io_write()<0)
@@ -559,13 +627,3 @@ service_handle*service_handle::instance(service_callback*sc)
 }
 }
 
 
 
 
-
-
-
-
-
-
-
-
-
-

+ 2 - 0
znet.h

@@ -14,6 +14,8 @@ struct client:std::enable_shared_from_this<client>
 	virtual void close()=0;
 	virtual void close()=0;
 	virtual void send(std::vector<char>&&b)=0;
 	virtual void send(std::vector<char>&&b)=0;
 
 
+	virtual bool check_timestamp(const char*)=0;
+
 	virtual ~client(){}
 	virtual ~client(){}
 };
 };