PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Modules/FileTransfer/FileTransferSocket.cpp

https://gitlab.com/yoage/TTWinClient
C++ | 397 lines | 342 code | 38 blank | 17 comment | 38 complexity | a86b1620097635222f45c93aa5aa721f MD5 | raw file
Possible License(s): LGPL-3.0
  1. /*******************************************************************************
  2. * @file FileTransferSocket.cpp 2014\8\30 13:32:37 $
  3. * @author 快刀<kuaidao@mogujie.com>
  4. * @brief 文件传输socket
  5. ******************************************************************************/
  6. #include "StdAfx.h"
  7. #include "FileTransferSocket.h"
  8. #include "FileTransferTask.h"
  9. #include "TransferManager.h"
  10. #include "TTLogic/ILogic.h"
  11. #include "TTLogic/TcpClientSocket.h"
  12. #include "src/base/ImPduFile.h"
  13. #include "src/base/ImPduClient.h"
  14. #include "Modules/IFileTransferModule.h"
  15. #include "Modules/IMiscModule.h"
  16. #include "Modules/ISysConfigModule.h"
  17. #include "utility/utilCommonAPI.h"
  18. #include "TransferFile.h"
  19. /******************************************************************************/
  20. FileTransferSocket::FileTransferSocket(std::string& taskId)
  21. :m_pLinkSocket(0)
  22. , m_pPingTimer(0)
  23. , m_Icallback(0)
  24. , m_sTaskId(taskId)
  25. {
  26. m_pLinkSocket = new logic::TcpClientSocket;
  27. }
  28. FileTransferSocket::~FileTransferSocket(void)
  29. {
  30. delete m_pLinkSocket;
  31. m_pLinkSocket = 0;
  32. }
  33. BOOL FileTransferSocket::create()
  34. {
  35. m_pLinkSocket->registerCB(this);
  36. BOOL bret = m_pLinkSocket->create();
  37. PTR_FALSE(bret);
  38. return TRUE;
  39. }
  40. BOOL FileTransferSocket::connect(const CString &linkaddr, UInt16 port)
  41. {
  42. BOOL bRet = m_pLinkSocket->connect(linkaddr, port);
  43. PTR_NULL(bRet);
  44. return TRUE;
  45. }
  46. BOOL FileTransferSocket::shutdown()
  47. {
  48. if (m_pLinkSocket)
  49. {
  50. m_pLinkSocket->closeSocket();
  51. m_pLinkSocket->shutdown();
  52. delete m_pLinkSocket;
  53. m_pLinkSocket = 0;
  54. }
  55. return TRUE;
  56. }
  57. void FileTransferSocket::sendPacket(CImPdu* pdu)
  58. {
  59. m_pLinkSocket->send((const char*)pdu->GetBuffer(), pdu->GetLength());
  60. }
  61. void FileTransferSocket::startHeartbeat()
  62. {
  63. if (!m_pPingTimer)
  64. m_pPingTimer = new PingFileSevTimer(this);
  65. logic::GetLogic()->scheduleTimer(m_pPingTimer, 5, TRUE);
  66. }
  67. void FileTransferSocket::stopHeartbeat()
  68. {
  69. if (m_pPingTimer)
  70. logic::GetLogic()->killTimer(m_pPingTimer);
  71. m_pPingTimer = 0;
  72. }
  73. void FileTransferSocket::onReceiveData(const char* data, UInt32 size)
  74. {
  75. CImPdu* pPdu = 0;
  76. try
  77. {
  78. pPdu = CImPdu::ReadPdu((uchar_t*)data, (uint32_t)size);
  79. PTR_VOID(pPdu);
  80. if (IM_PDU_TYPE_HEARTBEAT == pPdu->GetCommandId() && SID_OTHER == pPdu->GetModuleId())
  81. return;
  82. }
  83. catch (CPduException e)
  84. {
  85. APP_LOG(LOG_ERROR, _T("FileTransferSocket onPacket CPduException serviceId:%d,commandId:%d,errCode:%d")
  86. , e.GetModuleId(), e.GetCommandId(), e.GetErrorCode());
  87. return;
  88. }
  89. catch (...)
  90. {
  91. APP_LOG(LOG_ERROR, _T("FileTransferSocket onPacket unknown exception"));
  92. return;
  93. }
  94. UInt16 ncmdid = pPdu->GetCommandId();
  95. switch (pPdu->GetCommandId())
  96. {
  97. case CID_FILE_LOGIN_RES:
  98. _fileLoginResponse(pPdu);
  99. break;
  100. case CID_FILE_PULL_DATA_REQ:
  101. _filePullDataReqResponse(pPdu);
  102. break;
  103. case CID_FILE_PULL_DATA_RSP:
  104. _filePullDataRspResponse(pPdu);
  105. break;
  106. case CID_FILE_STATE:
  107. _fileState(pPdu);
  108. default:
  109. break;
  110. }
  111. delete pPdu;
  112. pPdu = 0;
  113. }
  114. void FileTransferSocket::onParseError()
  115. {
  116. APP_LOG(LOG_ERROR, _T("FileTransferSocket onParseError error"));
  117. }
  118. void FileTransferSocket::onConnectDone()
  119. {
  120. APP_LOG(LOG_INFO, _T("FileTransferSocket::onConnected()"));
  121. startHeartbeat();
  122. TransferFileEntity info;
  123. if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(m_sTaskId, info))
  124. return;
  125. //拉模式文件传输,传输taskid、token、client_mode
  126. CImPduClientFileLoginReq pduFileLoginReq(module::getSysConfigModule()->userID().c_str()
  127. , "", info.sTaskID.c_str(), info.nClientMode);
  128. sendPacket(&pduFileLoginReq);
  129. }
  130. void FileTransferSocket::onClose(int error)
  131. {
  132. APP_LOG(LOG_INFO, _T("FileTransferSocket::onClose error code:%d"), error);
  133. stopHeartbeat();
  134. }
  135. void FileTransferSocket::registerCB(logic::ITcpClientSocketCallback *cb)
  136. {
  137. m_Icallback = cb;
  138. }
  139. void FileTransferSocket::unRegisterCB()
  140. {
  141. m_Icallback = 0;
  142. }
  143. logic::ITcpClientSocketCallback* FileTransferSocket::getCallback()
  144. {
  145. return m_Icallback;
  146. }
  147. BOOL FileTransferSocket::startFileTransLink()
  148. {
  149. create();
  150. TransferFileEntity FileInfo;
  151. if (TransferFileEntityManager::getInstance()->getFileInfoByTaskId(m_sTaskId, FileInfo))
  152. {
  153. //大佛:使用msg server 传过来的IP和端口
  154. APP_LOG(LOG_INFO, _T("FileTransferSocket::startFileTransLink connect IP=%s,Port=%d"), util::stringToCString(FileInfo.sIP), FileInfo.nPort);
  155. connect(util::stringToCString(FileInfo.sIP), FileInfo.nPort);
  156. //connect(util::stringToCString(module::FILETRANSFER_IP), module::FILETRANSFER_PORT);
  157. return TRUE;
  158. }
  159. APP_LOG(LOG_ERROR, _T("FileTransferSocket::startFileTransLink can't find the TaskId"));
  160. return FALSE;
  161. }
  162. void FileTransferSocket::stopfileTransLink()
  163. {
  164. shutdown();
  165. stopHeartbeat();
  166. }
  167. void FileTransferSocket::_fileLoginResponse(CImPdu* pdu)
  168. {
  169. CImPduClientFileLoginRes* pData = (CImPduClientFileLoginRes*)pdu;
  170. if (!pData || pData->GetResult() != 0)
  171. {
  172. APP_LOG(LOG_ERROR, _T("file server login failed! "));
  173. return;
  174. }
  175. //打开文件
  176. std::string taskId(pData->GetTaskId(), pData->GetTaskIdLen());
  177. TransferFileEntity fileEntity;
  178. if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
  179. {
  180. APP_LOG(LOG_ERROR, _T("file server login:can't find the fileInfo "));
  181. return;
  182. }
  183. APP_LOG(LOG_INFO, _T("file server login succeed"));
  184. //提示界面,界面上插入该项
  185. if (CLIENT_REALTIME_SENDER == fileEntity.nClientMode
  186. || CLIENT_OFFLINE_UPLOAD == fileEntity.nClientMode)
  187. {
  188. logic::GetLogic()->asynNotifyObserver(module::KEY_FILETRANSFER_SENDFILE, fileEntity.sTaskID);
  189. }
  190. else if (CLIENT_REALTIME_RECVER == fileEntity.nClientMode
  191. || CLIENT_OFFLINE_DOWNLOAD == fileEntity.nClientMode)
  192. {
  193. logic::GetLogic()->asynNotifyObserver(module::KEY_FILETRANSFER_REQUEST, fileEntity.sTaskID);
  194. }
  195. }
  196. void FileTransferSocket::_filePullDataReqResponse(CImPdu* pdu)//发
  197. {
  198. CImPduClientFilePullDataReq* pData = (CImPduClientFilePullDataReq*)pdu;
  199. UInt32 fileSize = pData->GetDataSize();
  200. UInt32 fileOffset = pData->GetOffset();
  201. std::string taskId = std::string(pData->GetTaskId(),pData->GetTaskIdLen());
  202. TransferFileEntity fileEntity;
  203. if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
  204. {
  205. APP_LOG(LOG_ERROR, _T("PullDataReqResponse: can't find the fileInfo"));
  206. return;
  207. }
  208. APP_LOG(LOG_DEBUG, _T("send:taskId=%s,filesize=%d,name=%s")
  209. ,util::stringToCString(fileEntity.sTaskID)
  210. ,fileEntity.nFileSize
  211. ,fileEntity.getRealFileName());
  212. std::string buff;
  213. if (nullptr == fileEntity.pFileObject)
  214. {
  215. APP_LOG(LOG_ERROR, _T("PullDataReqResponse: file boject Destoryed!"));
  216. return;
  217. }
  218. fileEntity.pFileObject->readBlock(fileOffset, fileSize, buff);
  219. CImPduClientFilePullDataRsp pduPullDataRep(taskId.c_str()
  220. , fileEntity.sFromID.c_str(), fileOffset, fileSize, (uchar_t*)buff.data());
  221. sendPacket(&pduPullDataRep);
  222. fileEntity.nProgress = fileOffset + fileSize;
  223. if (fileEntity.nProgress <= fileEntity.nFileSize)
  224. {
  225. //更新进度条
  226. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
  227. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR, fileEntity.sTaskID);
  228. }
  229. else//传输完成
  230. {
  231. if (fileEntity.pFileObject)
  232. {
  233. delete fileEntity.pFileObject;
  234. fileEntity.pFileObject = nullptr;
  235. }
  236. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
  237. }
  238. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
  239. }
  240. void FileTransferSocket::_filePullDataRspResponse(CImPdu* pdu)//收
  241. {
  242. CImPduClientFilePullDataRsp* pDataRsp = (CImPduClientFilePullDataRsp*)pdu;
  243. UInt32 nRes = pDataRsp->GetResult();
  244. if (FILE_SERVER_ERRNO_OK != nRes)
  245. {
  246. APP_LOG(LOG_ERROR, _T("PullDataRspResponse: error result:%d"),nRes);
  247. return;
  248. }
  249. std::string taskId(pDataRsp->GetTaskId(), pDataRsp->GetTaskIdLen());
  250. void* pData = pDataRsp->GetData();
  251. UInt32 fileSize = pDataRsp->GetDataSize();
  252. UInt32 fileOffset = pDataRsp->GetOffset();
  253. TransferFileEntity fileEntity;
  254. if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
  255. {
  256. APP_LOG(LOG_ERROR, _T("PullDataRspResponse: can't find the fileInfo"));
  257. return;
  258. }
  259. APP_LOG(LOG_DEBUG, _T("receive:taskId=%s,filesize=%d,name=%s")
  260. , util::stringToCString(fileEntity.sTaskID)
  261. , fileEntity.nFileSize
  262. , fileEntity.getRealFileName());
  263. //存文件...
  264. if (!fileEntity.pFileObject->writeBlock(fileOffset, fileSize, pData))
  265. {
  266. APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_filePullDataRspResponse-writeBlock failed "));
  267. return;
  268. }
  269. fileEntity.nProgress = fileOffset + fileSize;
  270. if (fileEntity.nProgress <= fileEntity.nFileSize)
  271. {
  272. //更新进度条
  273. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
  274. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR, fileEntity.sTaskID);
  275. //继续发file block req...
  276. int mode = fileEntity.nClientMode == CLIENT_OFFLINE_DOWNLOAD ? FILE_TYPE_OFFLINE : FILE_TYPE_ONLINE;
  277. CImPduClientFilePullDataReq pduPullDataReq(taskId.c_str(), fileEntity.sToID.c_str()
  278. , mode, fileEntity.nProgress, fileSize);
  279. sendPacket(&pduPullDataReq);
  280. }
  281. else//传输完成
  282. {
  283. if (fileEntity.pFileObject)
  284. {
  285. delete fileEntity.pFileObject;
  286. fileEntity.pFileObject = nullptr;
  287. }
  288. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
  289. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
  290. }
  291. }
  292. void FileTransferSocket::_fileState(CImPdu* pdu)
  293. {
  294. CImPduClientFileState* pData = (CImPduClientFileState*)pdu;
  295. UINT32 nfileState = pData->GetState();
  296. std::string taskId(pData->GetTaskId(), pData->GetTaskIdLen());
  297. TransferFileEntity fileEntity;
  298. if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
  299. {
  300. APP_LOG(LOG_ERROR, _T("_fileState:can't find the fileInfo "));
  301. return;
  302. }
  303. switch (nfileState)
  304. {
  305. case CLIENT_FILE_PEER_READY:
  306. APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_fileState--CLIENT_FILE_PEER_READY "));
  307. break;
  308. case CLIENT_FILE_CANCEL://取消的了文件传输
  309. APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_fileState--CLIENT_FILE_CANCEL "));
  310. {
  311. delete fileEntity.pFileObject;
  312. fileEntity.pFileObject = nullptr;
  313. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
  314. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_CANCEL, fileEntity.sTaskID);
  315. }
  316. break;
  317. case CLIENT_FILE_REFUSE:
  318. APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_fileState--CLIENT_FILE_REFUSE "));
  319. {
  320. delete fileEntity.pFileObject;
  321. fileEntity.pFileObject = nullptr;
  322. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
  323. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_REJECT, fileEntity.sTaskID);
  324. }
  325. break;
  326. case CLIENT_FILE_DONE:
  327. APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_fileState--CLIENT_FILE_DONE "));
  328. if (fileEntity.pFileObject)
  329. {
  330. delete fileEntity.pFileObject;
  331. fileEntity.pFileObject = nullptr;
  332. }
  333. TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
  334. logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
  335. break;
  336. default:
  337. break;
  338. }
  339. }
  340. //////////////////////////////////////////////////////////////////////////
  341. void PingFileSevTimer::release()
  342. {
  343. delete this;
  344. }
  345. void PingFileSevTimer::process()
  346. {
  347. logic::GetLogic()->pushBackOperationWithLambda(
  348. [=]()
  349. {
  350. CImPduHeartbeat pduHeartbeat;
  351. m_pFileTransSocket->sendPacket(&pduHeartbeat);
  352. }
  353. );
  354. }
  355. PingFileSevTimer::PingFileSevTimer(FileTransferSocket* pTransSocket)
  356. :m_pFileTransSocket(pTransSocket)
  357. {
  358. }
  359. /******************************************************************************/