瀏覽代碼

改改改

zhangyang 6 年之前
父節點
當前提交
9a21ac8455

二進制
bin/Win32/Debug/zhipuzi_pos_windows/db/pos.db


二進制
bin/Win32/Debug/zhipuzi_pos_windows/zhipuzi_pos_windows.exe


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

@@ -24,6 +24,11 @@ debug_dbname = dispatch
 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://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/Win32/Debug/zhipuzi_pos_windows_server/db/pos.db


File diff suppressed because it is too large
+ 28185 - 0
bin/Win32/Debug/zhipuzi_pos_windows_server/log/pathplanning_server.log


+ 0 - 0
bin/Win32/Debug/zhipuzi_pos_windows_server/log/pathplanning_server_error.log


二進制
bin/Win32/Debug/zhipuzi_pos_windows_server/zhipuzi_pos_windows_server.exe


+ 23 - 5
lewaimai_dispatch/network/CMessagePush.cpp

@@ -94,6 +94,7 @@ void CMessagePush::KeepAlive()
 		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);
+		doc.AddMember("is_login", "0", allocator);
 
 		rapidjson::StringBuffer buffer;
 		rapidjson::Writer<StringBuffer> writer(buffer);
@@ -126,7 +127,25 @@ void CMessagePush::KeepAlive()
 
 				boost::asio::connect(socket_, endpoints);
 
-				socket_.write_some(boost::asio::buffer(m_keepalive_msg.c_str(), m_keepalive_msg.length()));
+				//刚刚连接上,这是第一次登陆,发送登陆信息
+				rapidjson::Document doc_1;
+				doc_1.SetObject();
+				rapidjson::Document::AllocatorType& allocator_1 = doc_1.GetAllocator(); //获取分配器
+
+				std::string username_1 = CSetting::getUsername();
+				std::string timestamp_1 = to_string(time(NULL));
+				doc_1.AddMember("username", StringRef(username_1.c_str(), username_1.length()), allocator_1);
+				doc_1.AddMember("timestamp", StringRef(timestamp_1.c_str(), timestamp_1.length()), allocator_1);
+				doc_1.AddMember("is_login", "1", allocator_1);
+
+				rapidjson::StringBuffer buffer_1;
+				rapidjson::Writer<StringBuffer> writer_1(buffer_1);
+				doc_1.Accept(writer_1);
+
+				//返回给接入层的消息
+				std::string m_login_message = buffer_1.GetString();
+
+				socket_.write_some(boost::asio::buffer(m_login_message.c_str(), m_login_message.length()));
 			}
 			catch (const std::exception& e)
 			{
@@ -173,13 +192,12 @@ void CMessagePush::ReceiveMessage()
 				return;
 			}
 
-			int type = document["type"].GetInt();
+			int type = document["msg_type"].GetInt();
 
 			if (type == 1)
 			{
-				std::string username = document["username"].GetString();
-				std::string order_id = document["order_id"].GetString();
-				std::string order_no = document["order_no"].GetString();
+				std::string order_id = document["waimai_order_id"].GetString();
+				std::string order_no = document["waimai_order_no"].GetString();
 
 				//新订单来了,首先判断是否要语音提醒
 				if (CSetting::GetParam("setting_is_new_waimai_voice") == "1")

+ 8 - 3
lewaimai_pathplanning/conf/pathplanning.conf

@@ -24,6 +24,11 @@ debug_dbname = dispatch
 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://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

+ 78 - 0
lewaimai_pathplanning/helper/CSystem.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../pch/pch.h"
+
 class CSystem
 {
 public:
@@ -10,5 +12,81 @@ public:
 
 	//程序休眠X秒
 	static void my_sleep(int second);
+
+	static std::wstring GetProgramDir()
+	{
+		wchar_t exeFullPath[MAX_PATH]; // Full path
+		std::wstring strPath = L"";
+
+		GetModuleFileName(NULL, exeFullPath, MAX_PATH);
+		strPath = (wstring)exeFullPath;    // Get full path of the file
+
+		int pos = strPath.find_last_of('\\', strPath.length());
+		return strPath.substr(0, pos);  // Return the directory without the file name
+	}
+
+	// 程序开机自动启动
+	static void autostart()
+	{
+		HKEY hKey;
+		wstring strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
+
+		//1、找到系统的启动项
+		if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)  ///打开启动项
+		{
+			//2、得到本程序自身的全路径
+			TCHAR strExeFullDir[MAX_PATH];
+			GetModuleFileName(NULL, strExeFullDir, MAX_PATH);
+
+			//3、添加一个子Key,并设置值,"GISRestart"是应用程序名字(不加后缀.exe)
+			RegSetValueEx(hKey, L"智铺子收银软件", 0, REG_SZ, (LPBYTE)strExeFullDir, (lstrlen(strExeFullDir) + 1) * sizeof(TCHAR));
+
+			//4、关闭注册表
+			RegCloseKey(hKey);
+		}
+
+		else
+		{
+			cout << "系统参数错误, 不能随系统启动";
+		}
+	}
+
+	// 取消开机自动启动
+	static void cancelAutoStart()
+	{
+		HKEY hKey;
+		wstring strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
+
+		//1、找到系统的启动项
+		if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
+		{
+			//2、删除值
+			RegDeleteValue(hKey, L"智铺子收银软件");
+
+			//3、关闭注册表
+			RegCloseKey(hKey);
+		}
+	}
+
+	// 判断文件是否存在
+	static BOOL IsFileExist(const wstring& csFile)
+	{
+		DWORD dwAttrib = GetFileAttributes(csFile.c_str());
+		return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 == (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
+	}
+
+	// 判断文件夹是否存在
+	static BOOL IsDirExist(const wstring& csDir)
+	{
+		DWORD dwAttrib = GetFileAttributes(csDir.c_str());
+		return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
+	}
+
+	// 判断文件或文件夹是否存在
+	static BOOL IsPathExist(const wstring& csPath)
+	{
+		DWORD dwAttrib = GetFileAttributes(csPath.c_str());
+		return INVALID_FILE_ATTRIBUTES != dwAttrib;
+	}
 };
 

+ 1 - 1
lewaimai_pathplanning/lewaimai_pathplanning_windows.vcxproj

@@ -132,7 +132,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalLibraryDirectories>$(SolutionDir)lib\debug</AdditionalLibraryDirectories>
-      <AdditionalDependencies>log4cplusUD.lib;libboost_date_time-vc141-mt-gd-x32-1_70.lib;libboost_regex-vc141-mt-gd-x32-1_70.lib;DbgHelp.lib;mnscpp.lib;libcurl_debug.lib;ssleay32MTd.lib;libeay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>log4cplusUD.lib;libboost_date_time-vc141-mt-gd-x32-1_70.lib;libboost_regex-vc141-mt-gd-x32-1_70.lib;DbgHelp.lib;mnscpp.lib;libcurl_debug.lib;ssleay32MTd.lib;libeay32MTd.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
       <IgnoreAllDefaultLibraries>
       </IgnoreAllDefaultLibraries>

+ 36 - 29
lewaimai_pathplanning/network/CClientSession.cpp

@@ -1,6 +1,7 @@
 #include "CClientSession.h"
 
 #include "CServer.h"
+#include <sqlite3/sqlite3.h>
 
 CClientSession::~CClientSession()
 {
@@ -23,10 +24,31 @@ void CClientSession::stop()
 
 void CClientSession::send_message(std::string msg)
 {
-    boost::asio::async_write(socket_,
-                             boost::asio::buffer(msg.c_str(), msg.length()),
-                             boost::bind(&CClientSession::handle_write, this,
-                                         boost::asio::placeholders::error));
+	try
+	{
+		socket_.write_some(boost::asio::buffer(msg.c_str(), msg.length()));
+	}
+	catch (const std::exception& e)
+	{
+		std::string err = e.what();
+
+		//先把socket关闭掉
+		socket_.close();
+
+		//可能客户端关掉了socket
+		if (m_username == "")
+		{
+			//说明这个socket还没获取过用户名
+			delete this;
+		}
+		else
+		{
+			//这种是已经绑定过用户名了
+			this->stop();
+
+			m_server->DeleteClient(m_username);
+		}
+	}
 }
 
 void CClientSession::SetServer(CServer* server)
@@ -52,12 +74,20 @@ void CClientSession::handle_read(const boost::system::error_code& error,
 
         std::string username = document["username"].GetString();
 		std::string timestamp = document["timestamp"].GetString();
+		std::string is_login = document["is_login"].GetString();
 
+		//这个用于判断是否成功绑定用户名了
 		m_username = username;
 
         //获取到用户名了,进行绑定
         m_server->BindUsername(username, this);
 
+		//绑定完了检查这个用户有没有离线消息
+		if (is_login == "1")
+		{
+			m_server->CheckOfflineMessage(username);
+		}
+
         //处理完了,重新读取
         memset(data_, 0, max_length);
 
@@ -68,31 +98,8 @@ void CClientSession::handle_read(const boost::system::error_code& error,
     }
     else
     {
-		//可能客户端关掉了socket
-		if (m_username == "")
-		{
-			//说明这个socket还没获取过用户名
-			delete this;
-		}
-		else
-		{
-			//这种是已经绑定过用户名了
-			this->stop();
-
-			m_server->DeleteClient(m_username);
-		}
-    }
-}
-
-void CClientSession::handle_write(const boost::system::error_code& error)
-{
-    if(!error)
-    {
-		//消息发送成功,继续查询是否有离线消息
+		socket_.close();
 
-    }
-    else
-    {
 		//可能客户端关掉了socket
 		if (m_username == "")
 		{
@@ -107,4 +114,4 @@ void CClientSession::handle_write(const boost::system::error_code& error)
 			m_server->DeleteClient(m_username);
 		}
     }
-}
+}

+ 0 - 2
lewaimai_pathplanning/network/CClientSession.h

@@ -43,8 +43,6 @@ private:
 	void handle_read(const boost::system::error_code& error,
 		size_t bytes_transferred);
 
-	void handle_write(const boost::system::error_code& error);
-
     tcp::socket socket_;
     enum { max_length = 1024 };
     char data_[max_length];

+ 230 - 17
lewaimai_pathplanning/network/CServer.cpp

@@ -1,9 +1,28 @@
-#include "CServer.h"
+#include "../pch/pch.h"
+#include "CServer.h"
 
 #include "../helper/CAliyunMNS.h"
 
+CServer::CServer()
+{
+
+}
+
+CServer::~CServer()
+{
+	delete acceptor_;
+
+	if (m_db != NULL)
+	{
+		sqlite3_close(m_db);
+	}
+}
+
 void CServer::Init()
 {
+	//初始化数据库
+	InitSqlLite();
+
 	//TCP服务器默认使用9001端口
 	m_port = 9001;
 
@@ -16,13 +35,199 @@ void CServer::Init()
 	start_aliyun_mns();
 
 	//任务队列,发送消息给客户端
-	std::thread t(&CServer::SendMessageToClient, this);
-	t.detach();
+	std::thread(&CServer::SendMessageToClient, this).detach();
+
+	std::thread(&CServer::HandleOfflineMessage, this).detach();
 
 	//开始异步执行
 	io_context_.run();
 }
 
+void CServer::InitSqlLite()
+{
+	wstring folderPath = CSystem::GetProgramDir() + L"\\db";
+	if (!CSystem::IsDirExist(folderPath))
+	{
+		bool flag = CreateDirectory(folderPath.c_str(), NULL);
+		bool a = flag;
+	}
+
+	//如果没有这个文件,这里会创建这个文件
+	wstring path = CSystem::GetProgramDir() + L"\\db\\pos.db";
+	string s_path = CLewaimaiString::UnicodeToUTF8(path);
+
+	m_rc = sqlite3_open(s_path.c_str(), &m_db);
+
+	if (m_rc)
+	{
+		LOG_INFO("Can't open database: " << sqlite3_errmsg(m_db));
+		return;
+	}
+
+	else
+	{
+		LOG_INFO("Opened database successfully");
+	}
+
+	//初始化数据表
+	std::string sql = "SELECT COUNT(*) FROM sqlite_master where type = 'table' and name = 'pos_message';";
+	sqlite3_stmt * stmt = NULL;
+
+	//读取厨房打印机的参数
+	if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+	{
+		if (sqlite3_step(stmt) == SQLITE_ROW)
+		{
+			int count = sqlite3_column_int(stmt, 0);
+
+			if (count == 0)
+			{
+				//说明没找到这个表,那么这个时候新建这个表,先释放前面的stmt
+				sqlite3_finalize(stmt);
+				stmt = NULL;
+
+				sql = "CREATE TABLE pos_message("  \
+					"id         INTEGER          PRIMARY KEY AUTOINCREMENT,"\
+					"username   CHAR(100)        NOT NULL," \
+					"due_time   CHAR(100)        NOT NULL," \
+					"data       CHAR(2000)       NOT NULL);";
+
+				if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+				{
+					//执行该语句
+					if (sqlite3_step(stmt) != SQLITE_DONE)
+					{
+						std::string err = sqlite3_errmsg(m_db);
+						LOG_INFO("create table fail: " << err.c_str());
+
+						sqlite3_finalize(stmt);
+						return;
+					}
+
+					//走到这里就是表创建成功了
+					LOG_INFO("create table success");
+					sqlite3_finalize(stmt);
+				}
+
+				else
+				{
+					LOG_INFO("create table prepare fail: " << sqlite3_errmsg(m_db));
+
+					sqlite3_finalize(stmt);
+
+					return;
+				}
+			}
+
+			else
+			{
+				//说明已经有这个表了,就不用再创建了
+				sqlite3_finalize(stmt);
+			}
+		}
+	}
+}
+
+bool CServer::AddMessageToDB(std::string username, std::string due_time, std::string data)
+{
+	int result = sqlite3_exec(m_db, "BEGIN;", 0, 0, 0);
+
+	std::string sql = "INSERT INTO pos_message (username, due_time, data) VALUES ('" + username + "' ,'" + due_time + "','" + data + "')";
+	result = sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
+
+	result = sqlite3_exec(m_db, "COMMIT;", 0, 0, 0);
+
+	if (result == SQLITE_OK)
+	{
+		LOG_INFO("save params success");
+		return true;
+	}
+
+	LOG_INFO("save params fail");
+	return false;
+}
+
+/*
+ *把要处理离线消息的用户名,加入到队列
+ **/
+void CServer::CheckOfflineMessage(std::string username)
+{
+	m_offlineMsg_mutex.lock();
+
+	m_offlineMsg.push(username);
+
+	m_offlineMsg_mutex.unlock();
+}
+
+void CServer::HandleOfflineMessage()
+{
+	while (1)
+	{
+		m_offlineMsg_mutex.lock();
+
+		if (m_offlineMsg.empty())
+		{
+			m_offlineMsg_mutex.unlock();
+
+			CSystem::my_sleep(1);
+
+			continue;
+		}
+
+		std::string username = m_offlineMsg.front();
+		m_offlineMsg.pop();
+
+		m_offlineMsg_mutex.unlock();
+
+		//先把过期的消息全部删除
+		std::string curTime = CLewaimaiTime::DatetimeToString(time(NULL));
+		std::string sql = "DELETE FROM pos_message WHERE username = '" + username + "' AND due_time <= '" + curTime + "';";
+		sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
+
+		//再看有没有剩余的离线消息
+		sql = "SELECT * FROM pos_message WHERE username = '" + username + "' AND due_time > '" + curTime + "';";
+		sqlite3_stmt * stmt = NULL;
+
+		if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, NULL) == SQLITE_OK)
+		{
+			while (sqlite3_step(stmt) == SQLITE_ROW)
+			{
+				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);
+
+				m_map_mutex.lock();
+				if (m_clients_map.find(username) == m_clients_map.end())
+				{
+					m_map_mutex.unlock();
+
+					//socket失效了,下次再处理
+					break;
+				}
+				else
+				{
+					CClientSession* session = m_clients_map[username];
+					m_map_mutex.unlock();
+
+					session->send_message(data);
+				}
+			}
+
+			sqlite3_finalize(stmt);
+		}
+
+		else
+		{
+			//异常情况
+			sqlite3_finalize(stmt);
+		}
+
+		//把所有数据库的离线消息都删掉
+		sql = "DELETE FROM pos_message WHERE username = '" + username + "';";
+		sqlite3_exec(m_db, sql.c_str(), 0, 0, 0);
+	}
+}
+
 void CServer::start_accept()
 {
 	//新建一个客户端会话
@@ -131,27 +336,34 @@ void CServer::ReceiveMNSMessage()
         }
 
         //处理消息类型
-		int type = document["msg_type"].GetInt();
+		std::string username = document["username"].GetString();
 		std::string timestamp = document["timestamp"].GetString();
 		std::string use_time = document["use_time"].GetString();
-		std::string username = document["username"].GetString();
-		std::string waimai_order_id = document["waimai_order_id"].GetString();
-		std::string waimai_order_no = document["waimai_order_no"].GetString();
+
+		rapidjson::Value& data = document["data"];
+
+		rapidjson::StringBuffer sbBuf;
+		rapidjson::Writer<rapidjson::StringBuffer> Writer(sbBuf);
+		data.Accept(Writer);
+		std::string strData = std::string(sbBuf.GetString());
 
 		//判断是否过期
-		if (abs(time(NULL) - atoi(timestamp.c_str())) > 1800)
+		if (time(NULL) > atoi(timestamp.c_str()) + atoi(use_time.c_str()))
 		{
-			//如果消息已经超过了30分钟,直接丢弃
+			//消息过了有效期,直接丢弃
 			continue;
 		}		
 
 		//把消息放进队列
 		CClientMessage newMessage;
-		newMessage.msg_type = type;
-		newMessage.timestamp = to_string((NULL));
 		newMessage.m_username = username;
-		newMessage.m_order_id = waimai_order_id;
-		newMessage.m_order_no = waimai_order_no;
+
+		time_t start = atoi(timestamp.c_str());
+		time_t due = atoi(use_time.c_str());
+		time_t end = start + due;
+		newMessage.m_due_time = CLewaimaiTime::DatetimeToString(end);
+
+		newMessage.m_data = strData;
 
 		m_queue_mutex.lock();
 		m_message_queue.push(newMessage);
@@ -183,6 +395,8 @@ void CServer::SendMessageToClient()
 		m_queue_mutex.unlock();
 
 		std::string username = msg.m_username;
+		std::string due_time = msg.m_due_time;
+		std::string data = msg.m_data;
 
 		//判断消息对应的用户是否在线,如果不在线就消息暂存在数据库
 		m_map_mutex.lock();
@@ -191,6 +405,7 @@ void CServer::SendMessageToClient()
 			m_map_mutex.unlock();
 
 			//客户端不在线,操作存数据库
+			AddMessageToDB(username, due_time, data);
 		}
 		else
 		{
@@ -198,10 +413,8 @@ void CServer::SendMessageToClient()
 
 			m_map_mutex.unlock();
 
-			//返回给接入层的消息
-			std::string res_msg = msg.toJson();
-
-			session->send_message(res_msg);
+			//直接把消息发给客户端
+			session->send_message(data);
 		}
 	}
 	

+ 22 - 33
lewaimai_pathplanning/network/CServer.h

@@ -3,50 +3,24 @@
 #include "../pch/pch.h"
 #include "CClientSession.h"
 
+#include <sqlite3/sqlite3.h>
+
 using boost::asio::ip::tcp;
 
 class CClientMessage
 {
 public:
-    int msg_type; //消息类型 0:新的外卖订单
-
-	std::string timestamp;
     std::string m_username;
-    std::string m_order_id;
-    std::string m_order_no;
-
-	std::string toJson()
-	{
-		rapidjson::Document doc;
-		doc.SetObject();
-		rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); //获取分配器
-
-		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);
-
-		rapidjson::StringBuffer buffer;
-		rapidjson::Writer<StringBuffer> writer(buffer);
-		doc.Accept(writer);
-
-		return buffer.GetString();
-	}
+	std::string m_due_time;
+	std::string m_data;
 };
 
 class CServer
 {
 public:
-    CServer()
-    {
-
-    }
+	CServer();
 
-	~CServer()
-	{
-		delete acceptor_;
-	}
+	~CServer();
 
 	void Init();
 
@@ -54,6 +28,14 @@ public:
 
 	void DeleteClient(std::string username);
 
+	void InitSqlLite();
+
+	bool AddMessageToDB(std::string username, std::string due_time, std::string data);
+
+	void CheckOfflineMessage(std::string username);
+
+	void HandleOfflineMessage();
+
 private:
     void start_aliyun_mns();
 
@@ -78,8 +60,15 @@ private:
 	std::map<std::string, CClientSession*> m_clients_map;
 	std::mutex m_map_mutex;
 
+	//处理离线消息的队列
+	std::queue<std::string> m_offlineMsg;
+	std::mutex m_offlineMsg_mutex;
+
 	int m_port;
 
 	int m_nClientCount = 0;
-};
 
+	int m_rc;
+
+	sqlite3* m_db = NULL;
+};