st_clientnode_basetrans.cpp 8.1 KB
Newer Older
丁劲犇's avatar
丁劲犇 已提交
1
#include "st_clientnode_basetrans.h"
2
#include "st_client_table.h"
3
#include <assert.h>
4
namespace ExampleServer{
丁劲犇's avatar
丁劲犇 已提交
5 6 7 8 9 10 11 12 13 14 15 16
	st_clientNode_baseTrans::st_clientNode_baseTrans(st_client_table * pClientTable, QObject * pClientSock ,QObject *parent) :
		zp_plTaskBase(parent)
	{
		m_bUUIDRecieved = false;
		m_currentReadOffset = 0;
		m_currentMessageSize = 0;
		m_pClientSock = pClientSock;
		m_uuid = 0xffffffff;//Not Valid
		m_pClientTable = pClientTable;
		bTermSet = false;
		m_last_Report = QDateTime::currentDateTime();
	}
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
	quint32 st_clientNode_baseTrans::uuid()
	{
		return m_uuid;
	}
	QObject * st_clientNode_baseTrans::sock()
	{
		return m_pClientSock;
	}
	bool st_clientNode_baseTrans::uuidValid()
	{
		return m_bUUIDRecieved;
	}
	QDateTime st_clientNode_baseTrans::lastActiveTime()
	{
		return m_last_Report;
	}
	qint32 st_clientNode_baseTrans::bytesLeft()
	{
35
		return m_currentHeader.data_length + sizeof(EXAMPLE_TRANS_MSG) - 1
36 37 38 39 40
				-m_currentMessageSize ;
	}
	//judge whether id is valid.
	bool st_clientNode_baseTrans::bIsValidUserId(quint32 id)
	{
丁劲犇's avatar
丁劲犇 已提交
41
		return id >=(unsigned int)0x00000002 && id <=(unsigned int)0xFFFFFFFE;
42 43
	}

丁劲犇's avatar
丁劲犇 已提交
44 45 46 47 48 49 50 51
	//The main functional method, will run in thread pool
	int st_clientNode_baseTrans::run()
	{
		if (bTermSet==true)
		{
			//qDebug()<<QString("%1(%2) Node Martked Deleted, return.\n").arg((unsigned int)this).arg(ref());
			return 0;
		}
52 53
		if (ref()>1)
			return -1;
丁劲犇's avatar
丁劲犇 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
		int nCurrSz = -1;
		int nMessage = m_nMessageBlockSize;
		while (--nMessage>=0 && nCurrSz!=0  )
		{
			QByteArray block;
			m_mutex_rawData.lock();
			if (m_list_RawData.size())
				block =  *m_list_RawData.begin();
			m_mutex_rawData.unlock();
			if (block.isEmpty()==false && block.isNull()==false)
			{
				m_currentReadOffset = filter_message(block,m_currentReadOffset);
				if (m_currentReadOffset >= block.size())
				{
					m_mutex_rawData.lock();
69 70 71 72
					if (m_list_RawData.empty()==false)
						m_list_RawData.pop_front();
					else
						assert(false);
丁劲犇's avatar
丁劲犇 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
					m_currentReadOffset = 0;
					m_mutex_rawData.unlock();
				}
			}
			else
			{
				m_mutex_rawData.lock();
				//pop empty cabs
				if (m_list_RawData.empty()==false)
					m_list_RawData.pop_front();
				m_mutex_rawData.unlock();
			}
			m_mutex_rawData.lock();
			nCurrSz = m_list_RawData.size();
			m_mutex_rawData.unlock();
		}
		m_mutex_rawData.lock();
		nCurrSz = m_list_RawData.size();
		m_mutex_rawData.unlock();
		if (nCurrSz==0)
			return 0;
		return -1;
	}
96

丁劲犇's avatar
丁劲犇 已提交
97 98 99 100 101
	//push new binary data into queue
	int st_clientNode_baseTrans::push_new_data(const  QByteArray &  dtarray)
	{
		int res = 0;
		m_mutex_rawData.lock();
102

丁劲犇's avatar
丁劲犇 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116
		m_list_RawData.push_back(dtarray);
		res = m_list_RawData.size();
		m_mutex_rawData.unlock();
		m_last_Report = QDateTime::currentDateTime();
		return res;
	}
	//!deal one message, affect m_currentRedOffset,m_currentMessageSize,m_currentHeader
	//!return bytes Used.
	int st_clientNode_baseTrans::filter_message(const QByteArray & block, int offset)
	{
		const int blocklen = block.length();
		while (blocklen>offset)
		{
			const char * dataptr = block.constData();
117

丁劲犇's avatar
丁劲犇 已提交
118 119 120 121 122 123 124 125
			//Recieve First 2 byte
			while (m_currentMessageSize<2 && blocklen>offset )
			{
				m_currentBlock.push_back(dataptr[offset++]);
				m_currentMessageSize++;
			}
			if (m_currentMessageSize < 2) //First 2 byte not complete
				continue;
126

丁劲犇's avatar
丁劲犇 已提交
127 128 129 130 131
			if (m_currentMessageSize==2)
			{
				const char * headerptr = m_currentBlock.constData();
				memcpy((void *)&m_currentHeader,headerptr,2);
			}
132

丁劲犇's avatar
丁劲犇 已提交
133 134 135 136
			const char * ptrCurrData = m_currentBlock.constData();
			//Heart Beating
			if (m_currentHeader.Mark == 0xBEBE)
			{
137
				while (m_currentMessageSize< sizeof(EXAMPLE_HEARTBEATING) && blocklen>offset )
丁劲犇's avatar
丁劲犇 已提交
138 139 140 141
				{
					m_currentBlock.push_back(dataptr[offset++]);
					m_currentMessageSize++;
				}
142
				if (m_currentMessageSize < sizeof(EXAMPLE_HEARTBEATING)) //Header not completed.
丁劲犇's avatar
丁劲犇 已提交
143 144 145
					continue;
				//Send back
				emit evt_SendDataToClient(this->sock(),m_currentBlock);
146 147 148 149 150 151 152 153 154 155 156 157 158
				//Try to Get UUID Immediately
				if (m_bUUIDRecieved==false)
				{
					EXAMPLE_HEARTBEATING * pHbMsg = (EXAMPLE_HEARTBEATING *)(ptrCurrData);
					if (bIsValidUserId(pHbMsg->source_id))
					{
						m_bUUIDRecieved = true;
						m_uuid =  pHbMsg->source_id;
						//regisit client node to hash-table;
						m_pClientTable->regisitClientUUID(this);
					}
				}

丁劲犇's avatar
丁劲犇 已提交
159 160 161 162 163 164 165 166
				//This Message is Over. Start a new one.
				m_currentMessageSize = 0;
				m_currentBlock = QByteArray();
				continue;
			}
			else if (m_currentHeader.Mark == 0x55AA)
				//Trans Message
			{
167
				while (m_currentMessageSize< sizeof(EXAMPLE_TRANS_MSG)-1 && blocklen>offset)
丁劲犇's avatar
丁劲犇 已提交
168 169 170 171
				{
					m_currentBlock.push_back(dataptr[offset++]);
					m_currentMessageSize++;
				}
172
				if (m_currentMessageSize < sizeof(EXAMPLE_TRANS_MSG)-1) //Header not completed.
丁劲犇's avatar
丁劲犇 已提交
173
					continue;
174
				else if (m_currentMessageSize == sizeof(EXAMPLE_TRANS_MSG)-1)//Header just  completed.
丁劲犇's avatar
丁劲犇 已提交
175 176
				{
					const char * headerptr = m_currentBlock.constData();
177
					memcpy((void *)&m_currentHeader,headerptr,sizeof(EXAMPLE_TRANS_MSG)-1);
178

丁劲犇's avatar
丁劲犇 已提交
179 180 181
					//continue reading if there is data left behind
					if (block.length()>offset)
					{
182
						qint32 bitLeft = m_currentHeader.data_length + sizeof(EXAMPLE_TRANS_MSG) - 1
丁劲犇's avatar
丁劲犇 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
								-m_currentMessageSize ;
						while (bitLeft>0 && blocklen>offset)
						{
							m_currentBlock.push_back(dataptr[offset++]);
							m_currentMessageSize++;
							bitLeft--;
						}
						//deal block, may be send data as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				}
				else
				{
					if (block.length()>offset)
					{
204
						qint32 bitLeft = m_currentHeader.data_length + sizeof(EXAMPLE_TRANS_MSG) - 1
丁劲犇's avatar
丁劲犇 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
								-m_currentMessageSize ;
						while (bitLeft>0 && blocklen>offset)
						{
							m_currentBlock.push_back(dataptr[offset++]);
							m_currentMessageSize++;
							bitLeft--;
						}
						//deal block, may be processed as soon as possible;
						deal_current_message_block();
						if (bitLeft>0)
							continue;
						//This Message is Over. Start a new one.
						m_currentMessageSize = 0;
						m_currentBlock = QByteArray();
						continue;
					}
				} // end if there is more bytes to append
			} //end deal trans message
			else
			{
丁劲犇's avatar
丁劲犇 已提交
225
				emit evt_Message(this,tr("Client Send a unknown start Header %1 %2. Close client immediately.")
丁劲犇's avatar
丁劲犇 已提交
226 227 228 229 230 231 232
								 .arg((int)(ptrCurrData[0])).arg((int)(ptrCurrData[1])));
				m_currentMessageSize = 0;
				m_currentBlock = QByteArray();
				offset = blocklen;
				emit evt_close_client(this->sock());
			}
		} // end while block len > offset
233

丁劲犇's avatar
丁劲犇 已提交
234 235 236 237 238 239 240 241
		return offset;
	}
	//in Trans-Level, do nothing.
	int st_clientNode_baseTrans::deal_current_message_block()
	{
		//First, get uuid as soon as possible
		if (m_bUUIDRecieved==false)
		{
242
			if (bIsValidUserId( m_currentHeader.source_id) )
丁劲犇's avatar
丁劲犇 已提交
243 244 245 246 247 248 249 250 251 252 253 254
			{
				m_bUUIDRecieved = true;
				m_uuid =  m_currentHeader.source_id;
				//regisit client node to hash-table;
				m_pClientTable->regisitClientUUID(this);
			}
			else if (m_currentHeader.source_id==0xffffffff)
			{
				//New clients
			}
			else //Invalid
			{
丁劲犇's avatar
丁劲犇 已提交
255
				emit evt_Message(this,tr("Client ID is invalid! Close client immediatly."));
丁劲犇's avatar
丁劲犇 已提交
256 257 258 259 260 261
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}
		}
		else
		{
262
			if (!( bIsValidUserId(m_currentHeader.source_id)
丁劲犇's avatar
丁劲犇 已提交
263 264
				  ||
				  (m_currentHeader.source_id==0xffffffff)
265 266
				  )
					)
丁劲犇's avatar
丁劲犇 已提交
267
			{
丁劲犇's avatar
丁劲犇 已提交
268
				emit evt_Message(this,tr("Client ID is invalid! Close client immediatly."));
丁劲犇's avatar
丁劲犇 已提交
269 270 271
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}
272 273 274 275 276 277 278 279
			if (bIsValidUserId(m_currentHeader.source_id)==true &&
					m_uuid != m_currentHeader.source_id)
			{
				emit evt_Message(this,tr("Client ID Changed in Runtime! Close client immediatly."));
				m_currentBlock = QByteArray();
				emit evt_close_client(this->sock());
			}

280

丁劲犇's avatar
丁劲犇 已提交
281
		}
282

丁劲犇's avatar
丁劲犇 已提交
283 284 285 286 287 288 289 290
		return 0;
	}
	void st_clientNode_baseTrans::CheckHeartBeating()
	{
		QDateTime dtm = QDateTime::currentDateTime();
		qint64 usc = this->m_last_Report.secsTo(dtm);
		if (usc >=m_pClientTable->heartBeatingThrd())
		{
丁劲犇's avatar
丁劲犇 已提交
291
			emit evt_Message(this,tr("Client ") + QString("%1").arg((unsigned int)((quint64)this)) + tr(" is dead, kick out."));
丁劲犇's avatar
丁劲犇 已提交
292 293 294
			emit evt_close_client(this->sock());
		}
	}
295
}