WebServer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #define WIN32_LEAN_AND_MEAN
  2. #include <stddef.h>
  3. #include <Windows.h>
  4. #include "DBConnect.h"
  5. #include "scoped_ptr.h"
  6. #include "IOBuffer.h"
  7. #include "rapidjson/rapidjson.h"
  8. #include "rapidjson/document.h"
  9. #include "rapidjson/istreamwrapper.h"
  10. #include "rapidjson/stringbuffer.h"
  11. #include "rapidjson/writer.h"
  12. #include "WebHandler.h"
  13. #include "UserManager.h"
  14. #include "WebServer.h"
  15. #include <string>
  16. CWebServer::CWebServer()
  17. {
  18. }
  19. CWebServer::~CWebServer()
  20. {
  21. websocket_thread.join();
  22. }
  23. void CWebServer::on_close(Server* s, websocketpp::connection_hdl hdl)
  24. {
  25. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  26. std::lock_guard<std::shared_mutex> l(lock);
  27. auto it = UserHandler.find(conInput);
  28. if (it != UserHandler.end())
  29. {
  30. CWebUserManager::GetInstance().Remove(it->second->GetId());
  31. rapidjson::StringBuffer strBuf;
  32. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  33. root.StartObject();
  34. root.Key("type");
  35. root.String(kNotify);
  36. root.Key("uid");
  37. root.Int(it->second->GetId());
  38. root.Key("state");
  39. root.Bool(false);
  40. root.EndObject();
  41. CWebUserManager::GetInstance().BroadCastUserState(it->second->GetId(), strBuf.GetString());
  42. it->second->OnClose();
  43. UserHandler.erase(it);
  44. }
  45. //DeleteClientConnection(hdl);
  46. }
  47. CWebServer& CWebServer::GetInstance()
  48. {
  49. static CWebServer s;
  50. return s;
  51. }
  52. void CWebServer::on_message(Server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
  53. /*
  54. hdl.lock().get() 获得连接标识
  55. msg->get_payload() 是收到的消息内容
  56. msg->get_opcode() 是收到消息的类型 ,包含:文本TEXT,二进制BINARY等等
  57. */
  58. try {
  59. //std::cout << msg->get_payload() << std::endl;
  60. std::string str = msg->get_payload();
  61. rapidjson::Document document;
  62. document.Parse(str.c_str());
  63. if (document.IsObject() || !document.HasParseError())
  64. {
  65. if (!document.HasMember("type") || !document["type"].IsString()) return;
  66. auto type = document["type"].GetString();
  67. auto it = MapFn.find(type);
  68. if (it != MapFn.end())
  69. {
  70. (this->*it->second)(document, hdl);
  71. }
  72. }
  73. }
  74. catch (websocketpp::exception const& e)
  75. {
  76. std::cout << "exception: " << e.what() << std::endl;
  77. }
  78. catch (std::exception& e)
  79. {
  80. std::cout << "exception: " << e.what() << std::endl;
  81. }
  82. catch (...)
  83. {
  84. }
  85. // try {
  86. // /*
  87. // 发送消息
  88. // s->send(
  89. // hdl, //连接
  90. // msg->get_payload(), //消息
  91. // msg->get_opcode());//消息类型
  92. // */
  93. // s->send(hdl, msg->get_payload(), msg->get_opcode());
  94. // }
  95. // catch (websocketpp::exception const & e) {
  96. // std::cout << "Echo failed because: "
  97. // << "(" << e.what() << ")" << std::endl;
  98. // }
  99. }
  100. int32_t CWebServer::GetId(websocketpp::connection_hdl hdl)
  101. {
  102. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  103. auto it = UserHandler.find(conInput);
  104. if (it != UserHandler.end())
  105. return it->second->GetId();
  106. return -1;
  107. }
  108. int CWebServer::Init(unsigned short usPort, const char* pBaseUri)
  109. {
  110. // MapFn.insert(make_pair(LOGIN, &CWebSocketServer::OnWebsocketLogin));
  111. // MapFn.insert(make_pair(ACTION, &CWebSocketServer::OnWebsocketAction));
  112. // MapFn.insert(std::make_pair(CONNECT, &CWebSocketServer::OnWebSocketConnect));
  113. // MapFn.insert(std::make_pair(CHAT, &CWebSocketServer::OnWebSocketChat));
  114. int nRet = 0;
  115. //m_usPort = usPort;
  116. //strcpy_s(m_szBaseUri, pBaseUri);
  117. MapFn.insert(make_pair(kReqVideo, &CWebServer::OnWebReqVideo));
  118. MapFn.insert(make_pair(kRepVideo, &CWebServer::OnWebRepVideo));
  119. MapFn.insert(make_pair(kSigin, &CWebServer::OnWebSigin));
  120. MapFn.insert(make_pair(kOffer, &CWebServer::OnWebOffer));
  121. MapFn.insert(make_pair(kAnswer, &CWebServer::OnWebAnswer));
  122. MapFn.insert(make_pair(kCandidate, &CWebServer::OnWebCadidate));
  123. MapFn.insert(make_pair(kLeave, &CWebServer::OnWebLeave));
  124. MapFn.insert(make_pair(kCancelReq, &CWebServer::OnWebCancelReq));
  125. MapFn.insert(make_pair(kHeartbit, &CWebServer::OnWebHeartbeat));
  126. try {
  127. // Set logging settings
  128. m_server.set_access_channels(websocketpp::log::alevel::devel);
  129. m_server.set_error_channels(websocketpp::log::elevel::devel);
  130. // Register our message handler
  131. m_server.set_message_handler(std::bind(&CWebServer::on_message, this, &m_server, ::_1, ::_2));
  132. // m_server.set_fail_handler(std::bind(&CWebSocketServer::on_fail, this, &m_server, ::_1));
  133. //m_server.set_open_handler(std::bind(&CWebSocketServer::on_open, this, &m_server, ::_1));
  134. m_server.set_close_handler(std::bind(&CWebServer::on_close, this, &m_server, ::_1));
  135. //m_server.set_validate_handler(std::bind(&CWebSocketServer::validate, this, &m_server, ::_1));
  136. // Initialize ASIO
  137. m_server.init_asio();
  138. m_server.set_reuse_addr(true);
  139. // Listen on port
  140. m_server.listen(usPort);
  141. // Start the server accept loop
  142. m_server.start_accept();
  143. // m_bThreadExit = false;
  144. websocket_thread = std::move(std::thread(std::bind(&CWebServer::ThreadProccess, this)));
  145. }
  146. catch (websocketpp::exception const& e) {
  147. std::cout << e.what() << std::endl;
  148. nRet = -1;
  149. }
  150. catch (const std::exception& e) {
  151. std::cout << e.what() << std::endl;
  152. nRet = -2;
  153. }
  154. catch (...) {
  155. std::cout << "other exception" << std::endl;
  156. nRet = -3;
  157. }
  158. return nRet;
  159. }
  160. int CWebServer::Uninit()
  161. {
  162. return 0;
  163. }
  164. int CWebServer::StopWork()
  165. {
  166. //stop
  167. //m_bThreadExit = true;
  168. m_server.stop();
  169. return 0;
  170. }
  171. int CWebServer::ThreadProccess()
  172. {
  173. m_server.run();
  174. return 0;
  175. }
  176. // 字符串分割
  177. int CWebServer::StringSplit(std::vector<std::string>& dst, const std::string& src, const std::string& separator)
  178. {
  179. if (src.empty() || separator.empty())
  180. return 0;
  181. int nCount = 0;
  182. std::string temp;
  183. size_t pos = 0, offset = 0;
  184. // 分割第1~n-1个
  185. while ((pos = src.find_first_of(separator, offset)) != std::string::npos)
  186. {
  187. temp = src.substr(offset, pos - offset);
  188. if (temp.length() > 0) {
  189. dst.push_back(temp);
  190. nCount++;
  191. }
  192. offset = pos + 1;
  193. }
  194. // 分割第n个
  195. temp = src.substr(offset, src.length() - offset);
  196. if (temp.length() > 0) {
  197. dst.push_back(temp);
  198. nCount++;
  199. }
  200. return nCount;
  201. }
  202. //去前后空格
  203. std::string& CWebServer::StringTrim(std::string& str)
  204. {
  205. if (str.empty()) {
  206. return str;
  207. }
  208. str.erase(0, str.find_first_not_of(" "));
  209. str.erase(str.find_last_not_of(" ") + 1);
  210. return str;
  211. }
  212. //获取请求命令与参数
  213. bool CWebServer::GetReqeustCommandAndParmeter(std::string strUri, std::string& strRequestOperateCommand, std::vector<KeyValue>& listRequestOperateParameter)
  214. {
  215. bool bRet = false;
  216. std::vector<std::string> vecRequest;
  217. int nRetSplit = StringSplit(vecRequest, strUri, "?");
  218. if (nRetSplit > 0)
  219. {
  220. if (vecRequest.size() == 1)
  221. {
  222. strRequestOperateCommand = vecRequest[0];
  223. }
  224. else if (vecRequest.size() > 1)
  225. {
  226. strRequestOperateCommand = vecRequest[0];
  227. std::string strRequestParameter = vecRequest[1];
  228. std::vector<std::string> vecParams;
  229. nRetSplit = StringSplit(vecParams, strRequestParameter, "&");
  230. if (nRetSplit > 0)
  231. {
  232. std::vector<std::string>::iterator iter, iterEnd;
  233. iter = vecParams.begin();
  234. iterEnd = vecParams.end();
  235. for (iter; iter != iterEnd; iter++)
  236. {
  237. std::vector<std::string> vecNameOrValue;
  238. nRetSplit = StringSplit(vecNameOrValue, *iter, "=");
  239. if (nRetSplit > 0)
  240. {
  241. KeyValue nvNameAndValue;
  242. nvNameAndValue.strKey = vecNameOrValue[0];
  243. nvNameAndValue.strValue = "";
  244. if (vecNameOrValue.size() > 1)
  245. {
  246. nvNameAndValue.strValue = vecNameOrValue[1];
  247. }
  248. //insert
  249. listRequestOperateParameter.push_back(nvNameAndValue);
  250. }
  251. }
  252. }
  253. }
  254. else
  255. {
  256. }
  257. }
  258. return bRet;
  259. }
  260. void CWebServer::OnWebReqVideo(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  261. {
  262. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  263. int32_t peer = value["peer"].GetInt();
  264. int32_t width = value["width"].GetInt();
  265. int32_t height = value["height"].GetInt();
  266. int32_t fps = value["fps"].GetInt();
  267. std::shared_lock<std::shared_mutex> l(lock);
  268. auto it = UserHandler.find(conInput);
  269. if (it != UserHandler.end())
  270. {
  271. it->second->OnWebReqVideo(peer, width, height, fps);
  272. }
  273. }
  274. void CWebServer::OnWebRepVideo(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  275. {
  276. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  277. int32_t peer = value["peer"].GetInt();
  278. std::string ret = value["ret"].GetString();
  279. int32_t width = value["width"].GetInt();
  280. int32_t height = value["height"].GetInt();
  281. int32_t fps = value["fps"].GetInt();
  282. std::shared_lock<std::shared_mutex> l(lock);
  283. auto it = UserHandler.find(conInput);
  284. if (it != UserHandler.end())
  285. {
  286. it->second->OnWebRepVideo(peer, ret, width, height, fps);
  287. }
  288. }
  289. void CWebServer::Write(websocketpp::connection_hdl connect_hdl, const char* buffer)
  290. {
  291. m_server.send(connect_hdl, buffer, websocketpp::frame::opcode::value::TEXT);
  292. }
  293. void CWebServer::OnWebSigin(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  294. {
  295. if (!value.HasMember("account") || value["password"].IsNull()) return;
  296. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  297. if (UserHandler.find(conInput) != UserHandler.end()) return;
  298. std::string account = value["account"].GetString();
  299. std::string password = value["password"].GetString();
  300. CQPtr<CConnectionPtr<sql::Connection>> Conn = CDBConnectPool::GetInstance().QueryConnect();
  301. scoped_ptr<sql::Statement> stmt = (*Conn.get())->createStatement();
  302. char sql[1024];
  303. int32_t id;
  304. sprintf_s(sql, "select id,name,cid from user where account=\'%s\' and password=MD5(\'%s\')", account.c_str(), password.c_str());
  305. scoped_ptr<sql::ResultSet> resultSet = stmt->executeQuery(sql);
  306. rapidjson::StringBuffer strBuf;
  307. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  308. root.StartObject();
  309. root.Key("type");
  310. root.String(kSigin);
  311. root.Key("ret");
  312. if (resultSet->next())
  313. {
  314. id = resultSet->getInt(1);
  315. std::string name = resultSet->getString(2).c_str();
  316. int32_t cid = resultSet->getInt(3);
  317. // = std::make_shared(new CWebMessageHandler(hdl));
  318. std::cout << cid << "," << id << "," << name << std::endl;
  319. root.String("OK");
  320. root.Key("name");
  321. root.String(name.c_str());
  322. root.Key("uid");
  323. root.Int(id);
  324. root.Key("company");
  325. root.Int(cid);
  326. websocketpp::connection_hdl handle;
  327. auto type = CWebUserManager::GetInstance().Find(id);
  328. if (type) {
  329. printf("Kick Off");
  330. rapidjson::StringBuffer strBuf;
  331. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  332. root.StartObject();
  333. root.Key("type");
  334. root.String(kKickOff);
  335. root.EndObject();
  336. CIOBuffer* pBuffer = CIOBuffer::Alloc();
  337. strcpy((char*)pBuffer->Buffer, strBuf.GetString());
  338. pBuffer->Length = strBuf.GetLength() + 1;
  339. Write(hdl, (char*)pBuffer->Buffer);
  340. pBuffer->Release();
  341. }
  342. else
  343. {
  344. std::shared_ptr<CWebHandler> ptr(new CWebHandler(this, id, cid, hdl));
  345. CWebUserManager::GetInstance().Add(ptr);
  346. UserHandler.insert(make_pair(conInput, ptr));
  347. }
  348. }
  349. else
  350. {
  351. root.String("ERROR");
  352. }
  353. root.EndObject();
  354. Write(hdl, strBuf.GetString());
  355. }
  356. void CWebServer::OnWebOffer(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  357. {
  358. if (value["peer"].IsNull() || !value["peer"].IsInt()) return;
  359. int32_t peer = value["peer"].GetInt();
  360. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  361. std::shared_lock<std::shared_mutex> l(lock);
  362. auto it = UserHandler.find(conInput);
  363. if (it == UserHandler.end()) return;
  364. int32_t id = it->second->GetId();
  365. if (id == -1) return;
  366. rapidjson::StringBuffer strBuf;
  367. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  368. root.StartObject();
  369. root.Key("type");
  370. root.String(kOffer);
  371. root.Key("peer");
  372. root.Int(id);
  373. root.Key("sdp");
  374. root.String(value["sdp"].GetString());
  375. root.EndObject();
  376. CIOBuffer* pBuffer = CIOBuffer::Alloc();
  377. strcpy((char*)pBuffer->Buffer, strBuf.GetString());
  378. pBuffer->Length = strBuf.GetLength() + 1;
  379. CWebUserManager::GetInstance().Write(peer, pBuffer);
  380. pBuffer->Release();
  381. }
  382. void CWebServer::OnWebAnswer(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  383. {
  384. if (value["peer"].IsNull() || !value["peer"].IsInt()) return;
  385. int32_t peer = value["peer"].GetInt();
  386. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  387. std::shared_lock<std::shared_mutex> l(lock);
  388. auto it = UserHandler.find(conInput);
  389. if (it != UserHandler.end())
  390. {
  391. int32_t id = it->second->GetId();
  392. if (id == -1) return;
  393. rapidjson::StringBuffer strBuf;
  394. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  395. root.StartObject();
  396. root.Key("type");
  397. root.String(kAnswer);
  398. root.Key("peer");
  399. root.Int(id);
  400. root.Key("sdp");
  401. std::string sdp = value["sdp"].GetString();
  402. root.String(sdp.c_str());
  403. root.EndObject();
  404. CIOBuffer* pBuffer = CIOBuffer::Alloc();
  405. strcpy((char*)pBuffer->Buffer, strBuf.GetString());
  406. pBuffer->Length = strBuf.GetLength() + 1;
  407. CWebUserManager::GetInstance().Write(peer, pBuffer);
  408. pBuffer->Release();
  409. }
  410. }
  411. void CWebServer::OnWebCadidate(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  412. {
  413. if (value["peer"].IsNull() || !value["peer"].IsInt()) return;
  414. int32_t peer = value["peer"].GetInt();
  415. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  416. std::shared_lock<std::shared_mutex> l(lock);
  417. auto it = UserHandler.find(conInput);
  418. if (it != UserHandler.end())
  419. {
  420. int32_t id = it->second->GetId();
  421. if (id == -1) return;
  422. rapidjson::StringBuffer strBuf;
  423. rapidjson::Writer<rapidjson::StringBuffer> root(strBuf);
  424. root.StartObject();
  425. root.Key("type");
  426. root.String(kCandidate);
  427. root.Key("peer");
  428. root.Int(id);
  429. root.Key("candidate");
  430. std::string candidate = value["candidate"].GetString();
  431. root.String(candidate.c_str());
  432. int32_t sdpMLineIndex = value["sdpMLineIndex"].GetInt();
  433. root.Key("sdpMLineIndex");
  434. root.Int(sdpMLineIndex);
  435. root.Key("sdpMid");
  436. std::string sdpMid = value["sdpMid"].GetString();
  437. root.String(sdpMid.c_str());
  438. root.EndObject();
  439. CIOBuffer* pBuffer = CIOBuffer::Alloc();
  440. strcpy((char*)pBuffer->Buffer, strBuf.GetString());
  441. pBuffer->Length = strBuf.GetLength() + 1;
  442. CWebUserManager::GetInstance().Write(peer, pBuffer);
  443. pBuffer->Release();
  444. }
  445. }
  446. void CWebServer::OnWebLeave(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  447. {
  448. if (value["peer"].IsNull() || !value["peer"].IsInt()) return;
  449. int32_t peer = value["peer"].GetInt();
  450. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  451. std::shared_lock<std::shared_mutex> l(lock);
  452. auto it = UserHandler.find(conInput);
  453. if (it != UserHandler.end())
  454. {
  455. int32_t id = it->second->GetId();
  456. it->second->OnWebLeave(peer);
  457. if (id == -1) return;
  458. }
  459. }
  460. void CWebServer::OnWebCancelReq(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  461. {
  462. std::shared_lock<std::shared_mutex> l(lock);
  463. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  464. auto it = UserHandler.find(conInput);
  465. int32_t peer = value["peer"].GetInt();
  466. if (it != UserHandler.end())
  467. {
  468. it->second->OnWebCancelReq(peer);
  469. }
  470. }
  471. void CWebServer::OnWebHeartbeat(rapidjson::Document& value, websocketpp::connection_hdl hdl)
  472. {
  473. Server::connection_ptr conInput = m_server.get_con_from_hdl(hdl);
  474. std::shared_lock<std::shared_mutex> l(lock);
  475. auto it = UserHandler.find(conInput);
  476. if (it != UserHandler.end())
  477. {
  478. it->second->OnWebHeartbeat();
  479. }
  480. }
  481. void CWebServer::Remove(websocketpp::connection_hdl connect_hdl)
  482. {
  483. Server::connection_ptr conInput = m_server.get_con_from_hdl(connect_hdl);
  484. std::lock_guard<std::shared_mutex> l(lock);
  485. auto it = UserHandler.find(conInput);
  486. if (it != UserHandler.end())
  487. {
  488. UserHandler.erase(it);
  489. }
  490. conInput->close(0, "");
  491. }