目录
1.ubuntu导入sql文件
2.用.c文件生成库文件
3.序列化 反序列化测试
4. 第一次用postman测试注册功能
5.用postman测试用户登录成功后跳转页面 ---302
6.项目网页聊天室总结
1.ubuntu导入sql文件
sql文件:

使用命令mysql -uroot -p
结果如下:

2.用.c文件生成库文件

3.序列化 反序列化测试
vi util.hpp:
static bool Serialize(Json::Value &value,std::string *jsonstr)
Json::StreamWriterBuilder swb;
Json::StreamWriter *sw = swb.newStreamWriter();
int ret = sw->write(value,&ss);
std::cout<<"json writer failed!\n";
static bool UnSerialize(const std::string &jsonstr,Json::Value *value)
Json::CharReaderBuilder crb;
Json::CharReader *cr = crb.newCharReader();
bool ret = cr->parse(jsonstr.c_str(),jsonstr.c_str() + jsonstr.size(),value,&err);
std::cout<<"json parse failed!"<
vi json_test.cpp:
std::string str = R"({"username":"wj","password":"1111"})";
im_sys::JsonUtil::UnSerialize(str,&val);
std::cout<"username"].asString()<
std::cout<"password"].asString()<
err["reason"] = "用户名已经被占用!";
im_sys::JsonUtil::Serialize(err,&buf);
std::cout<
测试结果:

4. 第一次用postman测试注册功能
server.hpp ---/register功能的相应实现
#define SERVER_PORT 20000
static struct mg_mgr *_mgr;
static void callback(struct mg_connection *c,int ev,void *ev_data,void *fn_data)
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
if(mg_http_match_uri(hm,"/register"))
JsonUtil::UnSerialize(hm->body.ptr,&user_info);
std::string username = user_info["username"].asString();
std::string password = user_info["password"].asString();
bool ret = _user->Exists(username);
err["reason"] = "用户名已经被占用";
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type:application/json\r\n";
mg_http_reply(c,400,header.c_str(),body.c_str());
ret = _user->Insert(username,password);
err["reason"] = "用户插入数据库失败!";
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type: application/json\r\n";
mg_http_reply(c,200,header.c_str(),body.c_str());
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type:application/json\r\n";
mg_http_reply(c,200,header.c_str(),body.c_str());
_mgr = new struct mg_mgr();
bool RunModule(int port = SERVER_PORT)
std::string addr = "0.0.0.0:";
addr += std::to_string(port);
auto res = mg_http_listen(_mgr,addr.c_str(),callback,_mgr);
std::cout<<"init http listen failed!\n";
struct mg_mgr *Server::_mgr = NULL;
UserTable * Server::_user = NULL;

makefile:
g++ -std=c++11 $^ -o $@ -L/usr/lib/mysql -lmysqlclient -L./lib -lmongoose -ljsoncpp
main.cpp:
im_sys::UserTable * _user = new im_sys::UserTable();
_user->UpdateStatus("王五",OFFLINE);
int status = _user->Status("王五");
else if(status == OFFLINE)
im_sys::Server *server = new im_sys::Server();
data.hpp:
#define DB_HOST "127.0.0.1"
static MYSQL *MysqlInit()
MYSQL *mysql = mysql_init(NULL);
std::cout<<"mysql init failed!\n";
if(mysql_real_connect(mysql,DB_HOST,DB_USER,DB_PASS,DB_NAME,0,NULL,0) == NULL)
std::cout<<"connect mysql server failed:"<<mysql_error(mysql)<
if(mysql_set_character_set(mysql,"utf8") != 0)
std::cout<<"set mysql client character failed!:"<<mysql_error(mysql)<
static void MysqlDestory(MYSQL *mysql)
static bool MysqlQuery(MYSQL *mysql,const std::string &sql)
int ret = mysql_query(mysql,sql.c_str());
std::cout<
std::cout<<"query failed:"<<mysql_error(mysql)<
bool Insert(const std::string &name,const std::string &pass)
#define USER_INSERT "insert im_user values(null,'%s',MD5('%s'),0,now(),now());"
sprintf(sql,USER_INSERT,name.c_str(),pass.c_str());
return MysqlQuery(_mysql,sql);
bool Exists(const std::string &name)
#define USER_EXISTS "select id from im_user where name='%s';"
sprintf(sql,USER_EXISTS,name.c_str());
bool ret = MysqlQuery(_mysql,sql);
MYSQL_RES *res = mysql_store_result(_mysql);
int num = mysql_num_rows(res);
bool UserPassCheck(const std::string &name,const std::string &pass)
#define USER_CHECK "select id from im_user where name='%s' and pass=MD5('%s');"
sprintf(sql,USER_CHECK,name.c_str(),pass.c_str());
bool ret = MysqlQuery(_mysql,sql);
MYSQL_RES *res = mysql_store_result(_mysql);
int num = mysql_num_rows(res);
int Status(const std::string &name)
#define USER_STATUS "select status from im_user where name='%s';"
sprintf(sql,USER_STATUS,name.c_str());
bool ret = MysqlQuery(_mysql,sql);
MYSQL_RES *res = mysql_store_result(_mysql);
int num = mysql_num_rows(res);
MYSQL_ROW row = mysql_fetch_row(res);
int status = std::stoi(row[0]);
bool UpdateStatus(const std::string &name,int status)
#define USER_UPDATE_STATUS "update im_user set status=%d,stime=now() where name='%s';"
sprintf(sql,USER_UPDATE_STATUS,status,name.c_str());
return MysqlQuery(_mysql,sql);
bool UpdatePasswd(const std::string &name,const std::string &pass)
#define USER_UPDATE_PASS "update im_user set pass=MD5('%s') where name='%s';"
sprintf(sql,USER_UPDATE_PASS,pass.c_str(),name.c_str());
return MysqlQuery(_mysql,sql);
结果如下:


5.用postman测试用户登录成功后跳转页面 ---302
server.hpp:
#define SERVER_PORT 20000
#define WWWROOT "./wwwroot/"
struct mg_connection *conn;
static struct mg_mgr *_mgr;
static std::unordered_map _session;
static std::string ConResp(bool res,const std::string &info)
JsonUtil::Serialize(err,&body);
static std::string CreateIMSession(struct mg_connection *c,const std::string &username)
s.session_id = std::to_string(time(NULL));
_session[s.session_id] = s;
static void Login(struct mg_connection *c,struct mg_http_message *hm)
JsonUtil::UnSerialize(hm->body.ptr,&user_info);
std::string username = user_info["username"].asString();
std::string password = user_info["password"].asString();
bool ret = _user->UserPassCheck(username,password);
std::string body = ConResp(false,"用户名密码错误");
std::string header = "Content-Type: application/json\r\n";
mg_http_reply(c,400,header.c_str(),body.c_str());
ret = _user->Status(username);
std::string body = ConResp(false,"用户已登录");
std::string header = "Content-Type: application/json\r\n";
mg_http_reply(c,400,header.c_str(),body.c_str());
std::string ssid = CreateIMSession(c,username);
ret = _user->UpdateStatus(username,ONLINE);
std::string body = ConResp(false,"修改用户状态失败");
std::string header = "Content-Type: application/json\r\n";
mg_http_reply(c,500,header.c_str(),body.c_str());
std::stringstream headers;
headers<< "Location: /chat.html\r\n";
headers <<"Set-Cookie: SSID=" <";Path=/\r\n";
std::string body = ConResp(true,"登录成功");
mg_http_reply(c,302,headers.str().c_str(),body.c_str());
static void Register(struct mg_connection *c,struct mg_http_message *hm)
JsonUtil::UnSerialize(hm->body.ptr,&user_info);
std::string username = user_info["username"].asString();
std::string password = user_info["password"].asString();
bool ret = _user->Exists(username);
err["reason"] = "用户名已经被占用";
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type:application/json\r\n";
mg_http_reply(c,400,header.c_str(),body.c_str());
ret = _user->Insert(username,password);
err["reason"] = "用户插入数据库失败!";
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type: application/json\r\n";
mg_http_reply(c,200,header.c_str(),body.c_str());
JsonUtil::Serialize(err,&body);
std::string header = "Content-Type:application/json\r\n";
mg_http_reply(c,200,header.c_str(),body.c_str());
static bool GetSession(struct mg_connection *c,IMSession *session)
auto it = _session.begin();
for(;it!=_session.end();++it)
static bool DelSession(IMSession &session)
auto it = _session.find(session.session_id);
std::cout<<"not find session\n";
static void ConnClose(struct mg_connection *c)
bool ret = GetSession(c,&session);
std::cout<<"have no session info!\n";
ret = _user->UpdateStatus(session.username,OFFLINE);
std::cout<<"update status offline failed!\n";
static void callback(struct mg_connection *c,int ev,void *ev_data,void *fn_data)
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
if(mg_http_match_uri(hm,"/register"))
else if(mg_http_match_uri(hm,"/login"))
else if(mg_http_match_uri(hm,"/cws"))
struct mg_http_serve_opts opts = {.root_dir = WWWROOT};
mg_http_serve_dir(c,hm,&opts);
else if(ev == MG_EV_WS_OPEN)
else if(ev == MG_EV_WS_MSG)
else if(ev == MG_EV_CLOSE)
_mgr = new struct mg_mgr();
bool RunModule(int port = SERVER_PORT)
std::string addr = "0.0.0.0:";
addr += std::to_string(port);
auto res = mg_http_listen(_mgr,addr.c_str(),callback,_mgr);
std::cout<<"init http listen failed!\n";
struct mg_mgr *Server::_mgr = NULL;
UserTable * Server::_user = NULL;
std::unordered_mapServer::_session;

makefile:
g++ -std=c++11 $^ -o $@ -L/usr/lib/mysql -lmysqlclient -L./lib -lmongoose -ljsoncpp
结果如下:


6.项目网页聊天室总结
环境搭建:
1)ubuntu安装mysql
https://blog.csdn.net/weixin_42209572/article/details/98983741
https://blog.csdn.net/weixin_42209572/article/details/98983741
2)ubuntu安装mongoose http库
链接:https://pan.baidu.com/s/1kMaSz5rduAr5Cs0a88LhrQ 提取码:1111
---主要用到了mongoose.c和mongoose.h两个文件
3)ubuntu安装jsoncpp库
(65条消息) Ubuntu16.04 jsoncpp 的安装_只此冒泡君的博客-CSDN博客_ubuntu安装jsoncpp
https://blog.csdn.net/qing310820/article/details/84283650
4)打开VM虚拟机,通过ifconfig获取主机名,在项目chat.html中修改ws_init方法中的主机名,端口号不用修改。
结果:
登录三个会话进行聊天,测试结果如下:

-
相关阅读:
Error response from daemon
设计模式-创建型模式-单例模式
list容器(20221117)
【路由优化】基于matlab随机搜索算法优化带有速度的路由网络【含Matlab源码 2046期】
模拟字符串函数
对数组进行扩容
C++中编写没有参数和返回值的函数
四种强大且隐秘的缓存
【SpringBoot】配置文件分类
CDN许可证申请
-
原文地址:https://blog.csdn.net/weixin_46153828/article/details/126340661