zhangyang 6 лет назад
Родитель
Сommit
e85c930c06

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


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


+ 34 - 0
bin/Win32/Debug/zhipuzi_pos_windows_server/conf/zhipuzi_pos_windows_server.conf

@@ -0,0 +1,34 @@
+#这个是调度中心的配置文件,“#"用来注释当前行
+
+#模式,debug或者release
+mode = debug
+
+#release环境的数据库参数
+release_host = rdsqnuyurqnuyur.mysql.rds.aliyuncs.com
+release_port = 3306
+release_username = liantongxue
+release_password = LewaimaiLongtailiDB200
+release_dbname = dispatch
+
+#release环境的队列参数
+release_pos_task_queue = zhipuzi-pos-windows-release
+
+#debug环境的数据库参数
+debug_host = rm-bp113vj32hrp7wpws.mysql.rds.aliyuncs.com
+debug_port = 3306
+debug_username = weixin
+debug_password = hhyz122131
+debug_dbname = dispatch
+
+#debug环境的队列参数
+debug_pos_task_queue = zhipuzi-pos-windows-dev
+
+#连接阿里云的mns需要用到的参数
+#mns.accountendpoint = https://1733013318510961.mns.cn-hangzhou.aliyuncs.com/
+#mns.accesskeyid = LTAIpYffXvFnEUzp
+#mns.accesskeysecret = F3lqBxo6Uj9pJpLs7btMW5u30X5uKB
+
+#乐外卖的
+mns.accountendpoint = https://1111769578085953.mns.cn-hangzhou.aliyuncs.com/
+mns.accesskeyid = 2HUnzc9XJV92PjvW
+mns.accesskeysecret = 20mMc8wuzlfC0r323b6oJqxlBPEyjW

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


Разница между файлами не показана из-за своего большого размера
+ 2281 - 0
bin/Win32/Debug/zhipuzi_pos_windows_server/log/pathplanning_server.log


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


+ 2 - 2
zhipuzi_pos_windows/network/CMessagePush.cpp

@@ -168,8 +168,8 @@ void CMessagePush::KeepAlive()
 				//关闭无效的连接
 				socket_.close();
 
-				//10秒后再重试
-				CSystem::my_sleep(10);
+				//30秒后再重试
+				CSystem::my_sleep(30);
 
 				continue;
 			}

BIN
zhipuzi_pos_windows/resource/duilib.ico


BIN
zhipuzi_pos_windows/resource/zhipuzi_pos_windows.aps


+ 33 - 31
zhipuzi_pos_windows_server/network/CClientSession.cpp

@@ -7,6 +7,7 @@
 
 CClientSession::~CClientSession()
 {
+	
 }
 
 void CClientSession::start()
@@ -17,14 +18,20 @@ void CClientSession::start()
 			boost::asio::placeholders::bytes_transferred));
 }
 
+/*
+ *服务器端主动关闭,才能调用这个函数
+ **/
 void CClientSession::stop()
 {
 	socket_.close();
 
-	delete this;
+	//注意这里不能调用delete this,因为后面会异步返回,要判断状态,如果这里delete了,后面就会内存越界
 }
 
-void CClientSession::send_message(std::string msg)
+/*
+ *同步发送消息,返回true表示发送成功,返回false表示发送失败
+ **/
+bool CClientSession::send_message(std::string msg)
 {
 	try
 	{
@@ -39,23 +46,11 @@ void CClientSession::send_message(std::string msg)
 	{
 		std::string err = e.what();
 
-		//先把socket关闭掉
-		socket_.close();
-
-		//可能客户端关掉了socket
-		if (m_username == "")
-		{
-			//说明这个socket还没获取过用户名
-			delete this;
-		}
-		else
-		{
-			//这种是已经绑定过用户名了
-			this->stop();
-
-			m_server->DeleteClient(m_username);
-		}
+		//注意这里是同步发送消息,这里不要处理socket的关闭和delete操作,让后面的异步读错误处理
+		return false;
 	}
+
+	return true;
 }
 
 void CClientSession::SetServer(CServer* server)
@@ -86,12 +81,12 @@ void CClientSession::handle_read(const boost::system::error_code& error,
 		//这个用于判断是否成功绑定用户名了
 		m_username = username;
 
-        //获取到用户名了,进行绑定
-        m_server->BindUsername(username, this);
-
-		//绑定完了检查这个用户有没有离线消息
 		if (is_login == "1")
 		{
+			//获取到用户名了,进行绑定
+			m_server->BindUsername(username, this);
+
+			//绑定完了检查这个用户有没有离线消息
 			m_server->CheckOfflineMessage(username);
 		}
 
@@ -103,20 +98,27 @@ void CClientSession::handle_read(const boost::system::error_code& error,
     }
     else
     {
-		socket_.close();
+		std::string err = error.message();
 
-		//可能客户端关掉了socket
-		if (m_username == "")
+		if (socket_.is_open())
 		{
-			//说明这个socket还没获取过用户名
-			delete this;
+			//这个是客户端断开了链接
+			if (m_username == "")
+			{
+				//说明这个socket还没获取过用户名
+				delete this;
+			}
+			else
+			{
+				m_server->DeleteClient(m_username);
+
+				delete this;
+			}
 		}
 		else
 		{
-			//这种是已经绑定过用户名了
-			this->stop();
-
-			m_server->DeleteClient(m_username);
+			//这个是服务端断开了链接
+			delete this;
 		}
     }
 }

+ 6 - 2
zhipuzi_pos_windows_server/network/CClientSession.h

@@ -28,7 +28,7 @@ public:
 
 	void stop();
 
-	void send_message(std::string msg);
+	bool send_message(std::string msg);
 
 	void SetNum(int m_num)
 	{
@@ -50,8 +50,12 @@ private:
 
 	CServer* m_server;
 
-	int m_nClientNum;
+	int m_nClientNum = 0;
 
+	//本连接对应的客户端用户名
 	std::string m_username = "";
+
+	bool is_stop_work = false;
+	std::mutex stop_mutex;
 };
 

+ 39 - 24
zhipuzi_pos_windows_server/network/CServer.cpp

@@ -31,13 +31,29 @@ void CServer::Init()
 	//开始监听客户端的消息
 	start_accept();
 
+	int n_cpu = CSystem::get_CPU_core_num();
+	LOG_INFO("cpu num:" << n_cpu);
+
 	//开始接受和处理mns的消息
-	start_aliyun_mns();
+	for (int i = 0; i < n_cpu * 2; i++)
+	{
+		std::thread t(&CServer::ReceiveMNSMessage, this);
+		t.detach();
+	}
 
 	//任务队列,发送消息给客户端
-	std::thread(&CServer::SendMessageToClient, this).detach();
+	for (int i = 0; i < n_cpu * 2; i++)
+	{
+		std::thread t(&CServer::SendMessageToClient, this);
+		t.detach();
+	}
 
-	std::thread(&CServer::HandleOfflineMessage, this).detach();
+	//处理离线消息的队列
+	for (int i = 0; i < n_cpu * 2; i++)
+	{
+		std::thread t(&CServer::HandleOfflineMessage, this);
+		t.detach();
+	}
 
 	//开始异步执行
 	io_context_.run();
@@ -192,6 +208,7 @@ void CServer::HandleOfflineMessage()
 		{
 			while (sqlite3_step(stmt) == SQLITE_ROW)
 			{
+				std::string id = (char*)sqlite3_column_text(stmt, 0);
 				std::string username = (char*)sqlite3_column_text(stmt, 1);
 				std::string due_time = (char*)sqlite3_column_text(stmt, 2);
 				std::string data = (char*)sqlite3_column_text(stmt, 3);
@@ -209,7 +226,18 @@ void CServer::HandleOfflineMessage()
 					CClientSession* session = m_clients_map[username];
 					m_map_mutex.unlock();
 
-					session->send_message(data);
+					bool ret = session->send_message(data);
+					if (ret == false)
+					{
+						//发送失败,把数据写会数据库,等下次发送
+						AddMessageToDB(username, due_time, data);
+
+						break;
+					}
+
+					//成功发送一条,这里就删除一条
+					sql = "DELETE FROM pos_message WHERE id = '" + id + "';";
+					sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
 				}
 			}
 
@@ -221,10 +249,6 @@ void CServer::HandleOfflineMessage()
 			//异常情况
 			sqlite3_finalize(stmt);
 		}
-
-		//把所有数据库的离线消息都删掉
-		//sql = "DELETE FROM pos_message WHERE username = '" + username + "';";
-		//sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
 	}
 }
 
@@ -268,7 +292,7 @@ void CServer::BindUsername(std::string username, CClientSession* session)
 
 	if (m_clients_map.find(username) != m_clients_map.end() && m_clients_map[username]->GetNum() < session->GetNum())
 	{
-		//之前已经存在了一个,先把直接的关闭掉
+		//之前已经存在了一个,先把直接的关闭掉(这个是服务器端主动的关闭)
 		m_clients_map[username]->stop();
 	}
 
@@ -289,20 +313,6 @@ void CServer::DeleteClient(std::string username)
 	m_map_mutex.unlock();
 }
 
-void CServer::start_aliyun_mns()
-{
-    //开启线程,监听消息
-    int n_cpu = CSystem::get_CPU_core_num();
-    LOG_INFO("cpu num:" << n_cpu);
-
-    //创建跟CPU核数2倍的线程数量来处理消息队列的消息
-    for(int i = 0; i < n_cpu * 2; i++)
-    {
-        std::thread t(&CServer::ReceiveMNSMessage, this);
-        t.detach();
-    }
-}
-
 /*
 *接收消息,并且对消息进行处理
 **/
@@ -414,7 +424,12 @@ void CServer::SendMessageToClient()
 			m_map_mutex.unlock();
 
 			//直接把消息发给客户端
-			session->send_message(data);
+			bool ret = session->send_message(data);
+			if (ret == false)
+			{
+				//如果发送失败了,把消息存回到数据库
+				AddMessageToDB(username, due_time, data);
+			}
 		}
 	}
 	

+ 0 - 2
zhipuzi_pos_windows_server/network/CServer.h

@@ -37,8 +37,6 @@ public:
 	void HandleOfflineMessage();
 
 private:
-    void start_aliyun_mns();
-
     void start_accept();
 
     void handle_accept(CClientSession* new_session,