Przeglądaj źródła

完善服务端

zhangyang 6 lat temu
rodzic
commit
1018be3669

BIN
bin/Win32/Debug/zhipuzi_pos_windows/db/pos.db


BIN
bin/Win32/Debug/zhipuzi_pos_windows/zhipuzi_pos_windows.exe


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/DuiLib_ud.dll


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/api-ms-win-crt-conio-l1-1-0.dll


+ 3 - 3
bin/Win32/Debug/zhipuzi_pos_windows_server/conf/pathplanning.conf

@@ -24,6 +24,6 @@ debug_dbname = dispatch
 debug_pos_task_queue = zhipuzi-pos-windows-dev
 
 #连接阿里云的mns需要用到的参数
-mns.accountendpoint = https://1111769578085953.mns.cn-hangzhou.aliyuncs.com/
-mns.accesskeyid = 2HUnzc9XJV92PjvW
-mns.accesskeysecret = 20mMc8wuzlfC0r323b6oJqxlBPEyjW
+mns.accountendpoint = https://1733013318510961.mns.cn-hangzhou.aliyuncs.com/
+mns.accesskeyid = LTAIpYffXvFnEUzp
+mns.accesskeysecret = F3lqBxo6Uj9pJpLs7btMW5u30X5uKB

BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/libcurl.dll


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/libeay32.dll


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/log4cplusUD.dll


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/ssleay32.dll


BIN
bin/Win32/Debug/zhipuzi_pos_windows_server/zhipuzi_pos_windows_server.exe


+ 8 - 15
lewaimai_dispatch/network/CMessagePush.cpp

@@ -91,7 +91,9 @@ void CMessagePush::KeepAlive()
 		rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); //获取分配器
 
 		std::string username = CSetting::getUsername();
+		std::string timestamp = to_string(time(NULL));
 		doc.AddMember("username", StringRef(username.c_str(), username.length()), allocator);
+		doc.AddMember("timestamp", StringRef(timestamp.c_str(), timestamp.length()), allocator);
 
 		rapidjson::StringBuffer buffer;
 		rapidjson::Writer<StringBuffer> writer(buffer);
@@ -173,16 +175,7 @@ void CMessagePush::ReceiveMessage()
 
 			int type = document["type"].GetInt();
 
-			if (type == 0)
-			{
-				std::string status = document["status"].GetString();
-
-				if (status == "ok")
-				{
-					//表示连接服务器成功了
-				}
-			}
-			else if (type == 1)
+			if (type == 1)
 			{
 				std::string username = document["username"].GetString();
 				std::string order_id = document["order_id"].GetString();
@@ -289,7 +282,7 @@ void CMessagePush::HandleVoice()
             continue;
         }
 
-        std::string order_id = m_voice_queue.back();
+        std::string order_id = m_voice_queue.front();
         m_voice_queue.pop();
 
         m_voice_mutex.unlock();
@@ -318,7 +311,7 @@ void CMessagePush::HandleConfirm()
             continue;
         }
 
-        std::string order_id = m_confirm_queue.back();
+        std::string order_id = m_confirm_queue.front();
         m_confirm_queue.pop();
 
         m_confirm_mutex.unlock();
@@ -344,7 +337,7 @@ void CMessagePush::HandlePrinter()
             continue;
         }
 
-        WaimaiPinterInfo printerInfo = m_printer_queue.back();
+        WaimaiPinterInfo printerInfo = m_printer_queue.front();
         std::string order_id = printerInfo.order_id;
         std::string order_no = printerInfo.order_no;
 
@@ -388,7 +381,7 @@ void CMessagePush::HandleShouyinPrinter()
             continue;
         }
 
-        CWaimaiOrder order = m_shouyin_printer_queue.back();
+        CWaimaiOrder order = m_shouyin_printer_queue.front();
 
         m_shouyin_printer_queue.pop();
 
@@ -415,7 +408,7 @@ void CMessagePush::HandleChufangPrinter()
             continue;
         }
 
-        CWaimaiOrder order = m_chufang_printer_queue.back();
+        CWaimaiOrder order = m_chufang_printer_queue.front();
 
         m_chufang_printer_queue.pop();
 

+ 3 - 3
lewaimai_pathplanning/conf/pathplanning.conf

@@ -24,6 +24,6 @@ debug_dbname = dispatch
 debug_pos_task_queue = zhipuzi-pos-windows-dev
 
 #连接阿里云的mns需要用到的参数
-mns.accountendpoint = https://1111769578085953.mns.cn-hangzhou.aliyuncs.com/
-mns.accesskeyid = 2HUnzc9XJV92PjvW
-mns.accesskeysecret = 20mMc8wuzlfC0r323b6oJqxlBPEyjW
+mns.accountendpoint = https://1733013318510961.mns.cn-hangzhou.aliyuncs.com/
+mns.accesskeyid = LTAIpYffXvFnEUzp
+mns.accesskeysecret = F3lqBxo6Uj9pJpLs7btMW5u30X5uKB

+ 4 - 4
lewaimai_pathplanning/lewaimai_pathplanning_windows.cpp

@@ -12,13 +12,13 @@ int main()
 
 	try
 	{
-		boost::asio::io_context io_context;
-
-		CServer s(io_context, 9001);
-		io_context.run();
+		//初始化服务器,开始监听和处理消息
+		CServer s;
+		s.Init();		
 	}
 	catch (std::exception& e)
 	{
 		std::cerr << "Exception: " << e.what() << "\n";
+		LOG_INFO("Exception: " << e.what());
 	}
 }

+ 1 - 2
lewaimai_pathplanning/lewaimai_pathplanning_windows.vcxproj

@@ -136,8 +136,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
       <AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
       <IgnoreAllDefaultLibraries>
       </IgnoreAllDefaultLibraries>
-      <IgnoreSpecificDefaultLibraries>
-      </IgnoreSpecificDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>LIBCMTD</IgnoreSpecificDefaultLibraries>
     </Link>
     <PostBuildEvent>
       <Command>mkdir $(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\

+ 37 - 22
lewaimai_pathplanning/network/CClientSession.cpp

@@ -14,6 +14,13 @@ void CClientSession::start()
                                         boost::asio::placeholders::bytes_transferred));
 }
 
+void CClientSession::stop()
+{
+	socket_.close();
+
+	delete this;
+}
+
 void CClientSession::send_message(std::string msg)
 {
     boost::asio::async_write(socket_,
@@ -44,30 +51,13 @@ void CClientSession::handle_read(const boost::system::error_code& error,
         }
 
         std::string username = document["username"].GetString();
+		std::string timestamp = document["timestamp"].GetString();
+
+		m_username = username;
 
         //获取到用户名了,进行绑定
         m_server->BindUsername(username, this);
 
-        //返回ok给客户端
-        rapidjson::Document doc;
-        doc.SetObject();
-        rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); //获取分配器
-
-		doc.AddMember("type", 0, allocator);
-        doc.AddMember("status", "ok", allocator);
-
-        rapidjson::StringBuffer buffer;
-        rapidjson::Writer<StringBuffer> writer(buffer);
-        doc.Accept(writer);
-
-        //返回给接入层的消息
-        std::string ok_msg = buffer.GetString();
-
-        boost::asio::async_write(socket_,
-                                 boost::asio::buffer(ok_msg.c_str(), ok_msg.length()),
-                                 boost::bind(&CClientSession::handle_write, this,
-                                             boost::asio::placeholders::error));
-
         //处理完了,重新读取
         memset(data_, 0, max_length);
 
@@ -78,7 +68,19 @@ void CClientSession::handle_read(const boost::system::error_code& error,
     }
     else
     {
-        delete this;
+		//可能客户端关掉了socket
+		if (m_username == "")
+		{
+			//说明这个socket还没获取过用户名
+			delete this;
+		}
+		else
+		{
+			//这种是已经绑定过用户名了
+			this->stop();
+
+			m_server->DeleteClient(m_username);
+		}
     }
 }
 
@@ -86,10 +88,23 @@ void CClientSession::handle_write(const boost::system::error_code& error)
 {
     if(!error)
     {
+		//消息发送成功,继续查询是否有离线消息
 
     }
     else
     {
-        delete this;
+		//可能客户端关掉了socket
+		if (m_username == "")
+		{
+			//说明这个socket还没获取过用户名
+			delete this;
+		}
+		else
+		{
+			//这种是已经绑定过用户名了
+			this->stop();
+
+			m_server->DeleteClient(m_username);
+		}
     }
 }

+ 16 - 0
lewaimai_pathplanning/network/CClientSession.h

@@ -25,8 +25,20 @@ public:
 
 	void start();
 
+	void stop();
+
 	void send_message(std::string msg);
 
+	void SetNum(int m_num)
+	{
+		m_nClientNum = m_num;
+	}
+
+	int GetNum()
+	{
+		return m_nClientNum;
+	}
+
 private:
 	void handle_read(const boost::system::error_code& error,
 		size_t bytes_transferred);
@@ -38,5 +50,9 @@ private:
     char data_[max_length];
 
 	CServer* m_server;
+
+	int m_nClientNum;
+
+	std::string m_username = "";
 };
 

+ 86 - 14
lewaimai_pathplanning/network/CServer.cpp

@@ -2,13 +2,38 @@
 
 #include "../helper/CAliyunMNS.h"
 
+void CServer::Init()
+{
+	//TCP服务器默认使用9001端口
+	m_port = 9001;
+
+	acceptor_ = new tcp::acceptor(io_context_, tcp::endpoint(tcp::v4(), m_port));
+
+	//开始监听客户端的消息
+	start_accept();
+
+	//开始接受和处理mns的消息
+	start_aliyun_mns();
+
+	//任务队列,发送消息给客户端
+	std::thread t(&CServer::SendMessageToClient, this);
+	t.detach();
+
+	//开始异步执行
+	io_context_.run();
+}
+
 void CServer::start_accept()
 {
 	//新建一个客户端会话
 	CClientSession* new_session = new CClientSession(io_context_);
 	new_session->SetServer(this);
 
-	acceptor_.async_accept(new_session->socket(),
+	//记录客户端的顺序
+	m_nClientCount++;
+	new_session->SetNum(m_nClientCount);
+
+	acceptor_->async_accept(new_session->socket(),
 		boost::bind(&CServer::handle_accept, this, new_session,
 			boost::asio::placeholders::error));
 }
@@ -25,12 +50,38 @@ void CServer::handle_accept(CClientSession* new_session,
 		delete new_session;
 	}
 
+	//继续监听下一个客户端
 	start_accept();
 }
 
+/*
+ *将客户端的用户名和socket进行绑定,每个用户名只能绑定一个socket,后登陆的会删掉前面先登录的
+ **/
 void CServer::BindUsername(std::string username, CClientSession* session)
 {
+	m_map_mutex.lock();
+
+	if (m_clients_map.find(username) != m_clients_map.end() && m_clients_map[username]->GetNum() < session->GetNum())
+	{
+		//之前已经存在了一个,先把直接的关闭掉
+		m_clients_map[username]->stop();
+	}
+
 	m_clients_map[username] = session;
+
+	m_map_mutex.unlock();
+}
+
+void CServer::DeleteClient(std::string username)
+{
+	m_map_mutex.lock();
+
+	if (m_clients_map.find(username) != m_clients_map.end())
+	{
+		m_clients_map.erase(username);
+	}
+
+	m_map_mutex.unlock();
 }
 
 void CServer::start_aliyun_mns()
@@ -79,18 +130,28 @@ void CServer::ReceiveMNSMessage()
             continue;
         }
 
-        //处理消息类型  { "username":"zhangyang","order_id":"86425730"}
-		int type = document["type"].GetInt();
+        //处理消息类型
+		int type = document["msg_type"].GetInt();
+		std::string timestamp = document["timestamp"].GetString();
+		std::string use_time = document["use_time"].GetString();
 		std::string username = document["username"].GetString();
-		std::string order_id = document["order_id"].GetString();
-		std::string order_no = document["order_no"].GetString();
+		std::string waimai_order_id = document["waimai_order_id"].GetString();
+		std::string waimai_order_no = document["waimai_order_no"].GetString();
 
-		//把消息放进队列,队列发给客户端
+		//判断是否过期
+		if (abs(time(NULL) - atoi(timestamp.c_str())) > 1800)
+		{
+			//如果消息已经超过了30分钟,直接丢弃
+			continue;
+		}		
+
+		//把消息放进队列
 		CClientMessage newMessage;
-		newMessage.m_type = type;
+		newMessage.msg_type = type;
+		newMessage.timestamp = to_string((NULL));
 		newMessage.m_username = username;
-		newMessage.m_order_id = order_id;
-		newMessage.m_order_no = order_no;
+		newMessage.m_order_id = waimai_order_id;
+		newMessage.m_order_no = waimai_order_no;
 
 		m_queue_mutex.lock();
 		m_message_queue.push(newMessage);
@@ -123,13 +184,24 @@ void CServer::SendMessageToClient()
 
 		std::string username = msg.m_username;
 
-		//返回给接入层的消息
-		std::string res_msg = msg.toJson();
+		//判断消息对应的用户是否在线,如果不在线就消息暂存在数据库
+		m_map_mutex.lock();
+		if (m_clients_map.find(username) == m_clients_map.end())
+		{
+			m_map_mutex.unlock();
 
-		//找到username对应的socket,然后发消息过去
-		if (m_clients_map.find(username) != m_clients_map.end())
+			//客户端不在线,操作存数据库
+		}
+		else
 		{
-			m_clients_map[username]->send_message(res_msg);
+			CClientSession* session = m_clients_map[username];
+
+			m_map_mutex.unlock();
+
+			//返回给接入层的消息
+			std::string res_msg = msg.toJson();
+
+			session->send_message(res_msg);
 		}
 	}
 	

+ 22 - 12
lewaimai_pathplanning/network/CServer.h

@@ -8,8 +8,9 @@ using boost::asio::ip::tcp;
 class CClientMessage
 {
 public:
-    int m_type; //消息类型 0:新的外卖订单
+    int msg_type; //消息类型 0:新的外卖订单
 
+	std::string timestamp;
     std::string m_username;
     std::string m_order_id;
     std::string m_order_no;
@@ -20,7 +21,8 @@ public:
 		doc.SetObject();
 		rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); //获取分配器
 
-		doc.AddMember("type", m_type, allocator);
+		doc.AddMember("msg_type", msg_type, allocator);
+		doc.AddMember("timestamp", rapidjson::StringRef(timestamp.c_str(), timestamp.size()), allocator);
 		doc.AddMember("username", rapidjson::StringRef(m_username.c_str(), m_username.size()), allocator);
 		doc.AddMember("order_id", rapidjson::StringRef(m_order_id.c_str(), m_order_id.size()), allocator);
 		doc.AddMember("order_no", rapidjson::StringRef(m_order_no.c_str(), m_order_no.size()), allocator);
@@ -36,20 +38,22 @@ public:
 class CServer
 {
 public:
-    CServer(boost::asio::io_context& io_context, short port)
-        : io_context_(io_context),
-          acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
+    CServer()
     {
-        start_accept();
 
-        start_aliyun_mns();
-
-        std::thread t(&CServer::SendMessageToClient, this);
-        t.detach();
     }
 
+	~CServer()
+	{
+		delete acceptor_;
+	}
+
+	void Init();
+
 	void BindUsername(std::string username, CClientSession* session);
 
+	void DeleteClient(std::string username);
+
 private:
     void start_aliyun_mns();
 
@@ -64,12 +68,18 @@ private:
     //开启线程,专门负责把消息发给客户端
     void SendMessageToClient();
 
-    boost::asio::io_context& io_context_;
-    tcp::acceptor acceptor_;
+    boost::asio::io_context io_context_;    
+	tcp::acceptor* acceptor_;
 
+	//给客户端发送消息的队列
     std::queue<CClientMessage> m_message_queue;
     std::mutex m_queue_mutex;
 
 	std::map<std::string, CClientSession*> m_clients_map;
+	std::mutex m_map_mutex;
+
+	int m_port;
+
+	int m_nClientCount = 0;
 };
 

BIN
lib/debug/libboost_date_time-vc141-mt-gd-x32-1_70.lib


BIN
lib/debug/libboost_regex-vc141-mt-gd-x32-1_70.lib


BIN
lib/debug/libcurl_debug.lib


BIN
lib/debug/libeay32MTd.lib


BIN
lib/debug/ssleay32MTd.lib