|
|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|