1、查看在线用户
客户端发送查看请求(只发送用户的名字),服务器将数据库中在线的用户查询出来并发送给客户端,客户端接收在线用户信息并作显示。
1.1、查看数据库的数据,在这里需要使用socket,所以我们在tcpclient.h里面写一个单例模式,那么在什么时候,都可以调用它
static TcpClient &getinstance();
TcpClient &TcpClient::getinstance()
{
static TcpClient instance;
return instance;
}
1.2、main.cpp里面就要修改为
#include "tcpclient.h"
#include <QApplication>
//#include "opewidget.h"
//#include "online.h"
//#include "friend.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// TcpClient w;
// w.show();
// OpeWidget w;
// w.show();
// Online w;
// w.show();
// Friend w;
// w.show();
TcpClient::getinstance().show();
return a.exec();
}
1.3、封装一个发送函数,获得他的引用
QTcpSocket &getTcpSocket();
QTcpSocket &TcpClient::getTcpSocket()
{
return m_tcpSocket;
}
1.4、打包封装,在friend.cpp里引入协议头文件
#include "protocal.h"
1.5、编辑消息类型
ENUM_MSG_TYPE_ALL_ONLINE_REQUEST, //在线用户请求
ENUM_MSG_TYPE_ALL_ONLINE_RESPOND, //在线用户回复
ENUM_MSG_TYPE_SEARCH_USER_REQUEST, //搜索用户请求
ENUM_MSG_TYPE_SEARCH_USER_RESPOND, //搜索用户回复
将服务器那边的协议也改过来
1.6、showonline进行定义
void Friend::showOnline()
{
//如果m_ponline是隐藏的,我们将他打开
if(m_pOnline->isHidden()){
m_pOnline->show();
PDU *pdu =mkPDU(0);//产生协议数据单元
pdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_REQUEST;
//将请求信息发送出去
TcpClient::getinstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);
//释放
free(pdu);
pdu = NULL;
}
else {
m_pOnline->hide();
}
}
1.7、服务器处理查看所有用户的请求
A、将所有在线用户的名字提取出来,返回,再通过socket写回到客户端
//-------------------------------查看所有用户的请求-----------------
case ENUM_MSG_TYPE_ALL_ONLINE_REQUEST:
{
break;
}
B、在数据库operatedb.cpp里面添加处理所有在线用户的函数
QStringList handleAllOnline();
添加函数定义
QStringList OperateDB::handleAllOnline()
{
QString data = QString("select name from usrInfo where online =1");
QSqlQuery query;
query.exec(data);
}
C、获得接口
QStringList OperateDB::handleAllOnline()
{
QString data = QString("select name from usrInfo where online =1");
QSqlQuery query;
query.exec(data);
QStringList result;
result.clear();
//循环的调用next函数,来获得每一条结果集
while (query.next()) {
result.append(query.value(0).toString());
}
return result;
}
D、返回到收数据的哪里
case ENUM_MSG_TYPE_ALL_ONLINE_REQUEST:
{
QStringList ret = OperateDB::getInstance().handleAllOnline();
//产生多大的pdu,每一个名字占32个字节大小
uint uiMsglen = ret.size()*32;
PDU *respdu = mkPDU(uiMsglen);
respdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_RESPOND;
//将用户名循环拷贝到这块空间里面去
for(int i=0; i<ret.size(); i++){
memcpy((char*)(respdu->caMsg)+i*32
,ret.at(i).toStdString().c_str()
, ret.at(i).size());
}
//发送
write((char*)respdu, respdu->uiPDULen);
//释放空间
free (respdu);
respdu =NULL;
break;
}
1.8、在客户端接收数据
A、在tcpclient里面,最终会将在线用户信息显示在好友界面上,所以我们在好友frend.h里面写一个显示在线用户函数
void ShowAllOnlineUser(PDU *pdu);
void Friend::ShowAllOnlineUser(PDU *pdu)
{
if(NULL==pdu){
return;
}
m_pOnline->showUsr(pdu);
}
B、在online.h里面定义函数
void showUsr(PDU *pdu);
void Online::showUsr(PDU *pdu)
{
if(NULL==pdu){
return;
}
//每32个给他拷贝出来
uint uiSize = pdu->uiMsgLen/32;
char caTmp[32];
for(uint i=0; i<uiSize; i++){
memcpy(caTmp, (char*)(pdu->caMsg)+i*32,32);
ui->online_lw->addItem(caTmp);
}
}
1.9、测试
A、运行服务器
没登陆之前数据库的online字段都是0
B、登录两个账号
C、点击显示在线用户,可以看到jack和lucy
成功