gstore源码解析(二):SOCKET网络服务源码解析
上一章我们介绍了基于boost实现的gstore http网络服务,本章将介绍基于TCP协议的socket网络服务。
gserver模块实现了一个基于TCP协议的socket网络服务,支持socket API双向通信。本章将从服务参数解析、运行机制、请求解析三个方面来展开。
gserver提供了丰富的操作参数,可以通过不同参数来进行一系列的操作,如启动、停止、重启服务、配置端口、查看端口等。实现的片段代码如下:
通过-h
或--help
参数查看帮助信息
else if (mode == "-h" || mode == "--help") {
cout << endl;
cout << "gStore Server (gServer)" << endl;
cout << endl;
cout << "Usage:\tbin/gserver [option]" << endl;
cout << endl;
cout << "Options:" << endl;
cout << "\t-h,--help\t\tDisplay this message." << endl;
cout << "\t-s,--start\t\tStart gServer." << endl;
cout << "\t-t,--stop\t\tStop gServer." << endl;
cout << "\t-r,--restart\t\tRestart gServer." << endl;
cout << "\t-p,--port [PORT=" << Socket::DEFAULT_CONNECT_PORT << "]\tChange connection port configuration, takes effect after restart if gServer running." << endl;
cout << "\t-P,--printport\t\tDisplay current connection port configuration." << endl;
cout << "\t-d,--debug\t\tStart gServer in debug mode (keep gServer in the foreground)." << endl;
cout << "\t-k,--kill\t\tKill existing gServer process(es), ONLY use when out of normal procedures." << endl;
cout << endl;
return 0;
}
通过-p
或--port
参数设置监听端口,如果不进行设置,默认监听端口为9000(Socket::DEFAULT_CONNECT_PORT)
if (mode == "-p" || mode == "--port") {
// 初始化端口为默认端口9000
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
if (argc == 3) {
if (!Util::isValidPort(string(argv[2]))) {
cerr << "Invalid port: " << argv[2] << endl;
return -1;
}
else {
stringstream ss(argv[2]);
ss >> port;
}
}
// 如果socket服务已启动,修改成功后需要重启后新端口才会生效
if (!isOnlyProcess(argv[0])) {
ofstream out(Util::gserver_port_swap.c_str());
if (!out) {
cerr << "Failed to change port!" << endl;
return -1;
}
out << port;
out.close();
cout << "Port will be changed to " << port << " after the current server stops or restarts." << endl;
return 0;
}
ofstream out(Util::gserver_port_file.c_str());
if (!out) {
cerr << "Failed to change port!" << endl;
return -1;
}
out << port;
out.close();
cout << "Port changed to " << port << '.' << endl;
return 0;
}
通过-s
或--start
参数启动服务
else if (mode == "-s" || mode == "--start") {
// 判断服务是否已存在
if (!isOnlyProcess(argv[0])) {
cerr << "gServer already running!" << endl;
return -1;
}
// 启动服务器,false表示非调试模式,在后面将介绍·
if (startServer(false)) {
sleep(1);
if (isOnlyProcess(argv[0])) {
cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl;
return -1;
}
return 0;
}
else {
return -1;
}
}
// startServer函数部分关键代码
bool startServer(bool _debug) {
// 从配置文件中读取配置的端口号,如果没有则为默认端口Socket::DEFAULT_CONNECT_PORT
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
ifstream in(Util::gserver_port_file.c_str());
if (!in) {
ofstream out(Util::gserver_port_file.c_str());
if (out) {
out << port;
out.close();
chmod(Util::gserver_port_file.c_str(), 0644);
}
}
....
// fock子进程,通过子进程启动服务,当子进程因某些异常被中断后,主进程将自动创建新的子进程
pid_t fpid = fork();
if (fpid == 0) {
if (!Util::dir_exist("logs")) {
Util::create_dir("logs");
}
freopen(Util::gserver_log.c_str(), "a", stdout);
freopen(Util::gserver_log.c_str(), "a", stderr);
int status;
while (true) {
fpid = fork();
if (fpid == 0) {
// 初始化服务
Server server(port);
if (!server.createConnection()) {
cerr << Util::getTimeString() << "Failed to create connection at port " << port << '.' << endl;
return false;
}
cout << Util::getTimeString() << "Server started at port " << port << '.' << endl;
// 启动监听,开始接收客户端的请求
server.listen();
server.deleteConnection();
exit(0);
return true;
}
......
}
}
.....
}
通过-t
或--stop
命令停止服务
else if (mode == "-t" || mode == "--stop") {
if (isOnlyProcess(argv[0])) {
cerr << "gServer not running!" << endl;
return -1;
}
// 通过发送socket api请求(op=stop)到服务端,由服务端进行停服处理
if (stopServer()) {
return 0;
}
else {
return -1;
}
}
通过-r
或--restart
命令重启服务
else if (mode == "-r" || mode == "--restart") {
// 判断服务是否在运行
if (isOnlyProcess(argv[0])) {
cerr << "gServer not running!" << endl;
return -1;
}
// 停止服务
if (!stopServer()) {
return -1;
}
// 启动服务
if (startServer(false)) {
sleep(1);
if (isOnlyProcess(argv[0])) {
cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl;
return -1;
}
return 0;
}
......
}
通过-p
或--printport
命令查看当前配置的端口
else if (mode == "-P" || mode == "--printport") {
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
ifstream in(Util::gserver_port_file.c_str());
if (in) {
in >> port;
in.close();
}
cout << "Current connection port is " << port << '.' << endl;
unsigned short portSwap = 0;
ifstream inSwap(Util::gserver_port_swap.c_str());
if (inSwap) {
inSwap >> portSwap;
inSwap.close();
}
if (portSwap != 0) {
cout << "Connection port to be changed to " << portSwap << '.' << endl;
}
return 0;
}
通过-k
后--kill
命令强制停止服务,当通过-t
无法正常停服时,可使用改命令强制停止
else if (mode == "-k" || mode == "--kill") {
if (isOnlyProcess(argv[0])) {
cerr << "No process to kill!" << endl;
return -1;
}
execl("/usr/bin/killall", "killall", Util::getExactPath(argv[0]).c_str(), NULL);
return 0;
}
在前面介绍中,通过-s
或--start
参数启动服务后,将在startServer函数中fork一个子进程,并通过子进程完成服务的初始化和监听,等待客户端的连接请求。部分关键代码解析如下:
服务初始化并绑定端口
// 源码路径:Server/Server.cpp Server/Socket.cpp
bool Server::createConnection(){
bool flag;
// 调用Socket::create创建socket
flag = this->socket.create();
if (!flag){
cerr << Util::getTimeString() << "Cannot create socket.@Server::createConnection" << endl;
return false;
}
// 调用Socket::bind绑定端口
flag = this->socket.bind(this->connectionPort);
if (!flag)
{
cerr << Util::getTimeString() << "Cannot bind to port " << this->connectionPort << ". @Server::createConnection" << endl;
return false;
}
// 开启请求监听
flag = this->socket.listen();
if (!flag)
{
cerr << Util::getTimeString() << "Cannot listen to port" << this->connectionPort << ". @Server::createConnection" << endl;
return false;
}
return true;
}
监听连接,当有新的请求进来后,会创建一个子线程去处理请求,函数的代码片段如下:
void Server::listen(){
this->init();
Socket soc[this->connectionMaxNum];
int i = 0;
Socket new_server_socket;
while (true)
{
/**
* @brief Receive the stopServer signal.
*/
signal(SIGTERM, Server::stop_sigterm_handler);
cout << Util::getTimeString() << "Wait for connection..." << endl;
// 等待连接请求
this->socket.accept(new_server_socket);
cout << Util::getTimeString() << "Accept a new socket connection." << endl;
/**
* @brief Create a thread for a client socket.
*/
memcpy(&soc[i], &new_server_socket, sizeof(Socket));
sockThread* tid = new sockThread(soc[i++]);
tid->server = this;
tid->start();
}
}
// 子线程的关键代码段如下
void sockThread::run()
{
cout << Util::getTimeString() << "Thread:" << tid << " run\n";
server->handler(socket);
}
// 通过thread::detach()分离主线程
void sockThread::start()
{
TD = std::thread(&sockThread::run, this);
TD.detach();
}
在运行机制中介绍了通过创建子线程来处理每个请求,在sockThread::run()
函数中,请求最终将调用Server::handler(Socket& _socket)
方法进行统一处理并返回处理结果,部分代码片段如下:
void
Server::handler(Socket& _socket) {
int repeated_num = 0;
while (true) {
// 10次尝试仍未成功将关闭该次请求
if (repeated_num > 10)
break;
/**
* @brief Receive the command message from the client.
*/
std::string recv_cmd;
// 接收请求的数据
bool recv_return = _socket.recv(recv_cmd);
if (!recv_return)
{
cerr << Util::getTimeString() << "Receive command from client error.@Server::listen" << endl;
repeated_num++;
continue;
}
cout << Util::getTimeString() << "Received msg: " << recv_cmd << endl;
......
}
}
在正确接收到客户端请求的数据后,将对数据进行解析并调用对应的方法进行处理,socket api请求的数据格式为JSON字符串,格式如下:
{"op":"[op_type]","[param1]":"[value1]","[param2]":"[value2]"……}
op为指令参数,[paramx]为不同接口要求的参数,op参数对应的类型如下:
// Server/Operation.h
enum CommandType {
CMD_OTHER, /**< enum value other. */
CMD_TEST, /**< enum value test. */
CMD_LOGIN, /**< enum value login. */
CMD_BUILD, /**< enum value build. */
CMD_LOAD, /**< enum value load. */
CMD_UNLOAD, /**< enum value unload. */
CMD_QUERY, /**< enum value query. */
CMD_SHOW, /**< enum value show. */
CMD_STOP, /**< enum value stop. */
CMD_DROP, /**< enum value drop. */
CMD_CLOSE /**< enum value close. */
};
// Server/Server.cpp
bool Server::parser(std::string _raw_cmd, Operation& _ret_oprt) {
......
if (cmd == "test") { //心跳检测
_ret_oprt.setCommand(CMD_TEST);
}
if (cmd == "login") {//登录
_ret_oprt.setCommand(CMD_LOGIN);
......
}
else if (cmd == "build") {//创建
_ret_oprt.setCommand(CMD_BUILD);
......
}
else if (cmd == "load") {//加载
_ret_oprt.setCommand(CMD_LOAD);
......
}
else if (cmd == "unload") {//卸载
_ret_oprt.setCommand(CMD_UNLOAD);
......
}
else if (cmd == "query") {//查询
_ret_oprt.setCommand(CMD_QUERY);
......
}
else if (cmd == "show") {//查看库
_ret_oprt.setCommand(CMD_SHOW);
......
}
else if (cmd == "stop") {//停止服务
_ret_oprt.setCommand(CMD_STOP);
......
}
else if (cmd == "close") {//关闭连接
_ret_oprt.setCommand(CMD_CLOSE);
......
}
else if (cmd == "drop") {//删除库
_ret_oprt.setCommand(CMD_DROP);
......
}
......
}
通过op
参数来识别请求的接口,并调用对应的接口函数进行处理,部分代码片段如下:
void
Server::handler(Socket& _socket)
{
int repeated_num = 0;
while (true)
{
......
/**
* @brief Execute the specific command function.
*/
std::string ret_msg;
CommandType cmd_type = operation.getCommand();
bool _close = false;
switch (cmd_type)
{
case CMD_TEST: //心跳检测
{
ret_msg = "OK";
break;
}
case CMD_LOGIN://登录
{
std::string username = operation.getParameter("username");
std::string password = operation.getParameter("password");
this->login(username, password, _socket);
break;
}
case CMD_LOAD://加载库
{
std::string db_name = operation.getParameter("db_name");
this->load(db_name, _socket);
break;
}
case CMD_UNLOAD://卸载库
{
std::string db_name = operation.getParameter("db_name");
this->unload(db_name, _socket);
break;
}
case CMD_BUILD://创建库
{
std::string db_name = operation.getParameter("db_name");
std::string db_path = operation.getParameter("db_path");
this->build(db_name, db_path, _socket);
break;
}
case CMD_DROP://删除库
{
std::string db_name = operation.getParameter("db_name");
this->drop(db_name, _socket);
break;
}
case CMD_QUERY://查询
{
std::string db_name = operation.getParameter("db_name");
std::string sparql = operation.getParameter("sparql");
pthread_t timer = Server::start_timer();
if (timer == 0) {
cerr << Util::getTimeString() << "Failed to start timer." << endl;
}
this->query(db_name, sparql, _socket);
if (timer != 0 && !Server::stop_timer(timer)) {
cerr << Util::getTimeString() << "Failed to stop timer." << endl;
}
break;
}
case CMD_SHOW://查看库
{
this->show(_socket);
break;
}
case CMD_STOP://停止服务
{
this->stopServer(_socket);
_stop = true;
_close = true;
break;
}
case CMD_CLOSE://关闭连接
{
this->closeConnection(_socket);
_close = true;
break;
}
......
}
......
}
各接口函数的实现逻辑与ghttp模块的接口函数基本相同,这里将不再重复进行介绍,各接口的使用说明可查阅文章#gStore-weekly | gStore最新版本0.9.1之gServer详解(上)和#gStore-weekly | gStore最新版本0.9.1之gServer详解(下)。
本章节介绍了socket网络服务gserver模块,如何实现服务参数解析、服务运行机制以及请求的处理逻辑,建议在阅读的同时结合源码Main/gserver.cpp一起分析,会更容易理解。下一章将开始介绍gstore的安全机制系列源码。gstore源码解析(二):SOCKET网络服务源码解析
上一章我们介绍了基于boost实现的gstore http网络服务,本章将介绍基于TCP协议的socket网络服务。
gserver模块实现了一个基于TCP协议的socket网络服务,支持socket API双向通信。本章将从服务参数解析、运行机制、请求解析三个方面来展开。
gserver提供了丰富的操作参数,可以通过不同参数来进行一系列的操作,如启动、停止、重启服务、配置端口、查看端口等。实现的片段代码如下:
通过-h
或--help
参数查看帮助信息
else if (mode == "-h" || mode == "--help") {
cout << endl;
cout << "gStore Server (gServer)" << endl;
cout << endl;
cout << "Usage:\tbin/gserver [option]" << endl;
cout << endl;
cout << "Options:" << endl;
cout << "\t-h,--help\t\tDisplay this message." << endl;
cout << "\t-s,--start\t\tStart gServer." << endl;
cout << "\t-t,--stop\t\tStop gServer." << endl;
cout << "\t-r,--restart\t\tRestart gServer." << endl;
cout << "\t-p,--port [PORT=" << Socket::DEFAULT_CONNECT_PORT << "]\tChange connection port configuration, takes effect after restart if gServer running." << endl;
cout << "\t-P,--printport\t\tDisplay current connection port configuration." << endl;
cout << "\t-d,--debug\t\tStart gServer in debug mode (keep gServer in the foreground)." << endl;
cout << "\t-k,--kill\t\tKill existing gServer process(es), ONLY use when out of normal procedures." << endl;
cout << endl;
return 0;
}
通过-p
或--port
参数设置监听端口,如果不进行设置,默认监听端口为9000(Socket::DEFAULT_CONNECT_PORT)
if (mode == "-p" || mode == "--port") {
// 初始化端口为默认端口9000
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
if (argc == 3) {
if (!Util::isValidPort(string(argv[2]))) {
cerr << "Invalid port: " << argv[2] << endl;
return -1;
}
else {
stringstream ss(argv[2]);
ss >> port;
}
}
// 如果socket服务已启动,修改成功后需要重启后新端口才会生效
if (!isOnlyProcess(argv[0])) {
ofstream out(Util::gserver_port_swap.c_str());
if (!out) {
cerr << "Failed to change port!" << endl;
return -1;
}
out << port;
out.close();
cout << "Port will be changed to " << port << " after the current server stops or restarts." << endl;
return 0;
}
ofstream out(Util::gserver_port_file.c_str());
if (!out) {
cerr << "Failed to change port!" << endl;
return -1;
}
out << port;
out.close();
cout << "Port changed to " << port << '.' << endl;
return 0;
}
通过-s
或--start
参数启动服务
else if (mode == "-s" || mode == "--start") {
// 判断服务是否已存在
if (!isOnlyProcess(argv[0])) {
cerr << "gServer already running!" << endl;
return -1;
}
// 启动服务器,false表示非调试模式,在后面将介绍·
if (startServer(false)) {
sleep(1);
if (isOnlyProcess(argv[0])) {
cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl;
return -1;
}
return 0;
}
else {
return -1;
}
}
// startServer函数部分关键代码
bool startServer(bool _debug) {
// 从配置文件中读取配置的端口号,如果没有则为默认端口Socket::DEFAULT_CONNECT_PORT
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
ifstream in(Util::gserver_port_file.c_str());
if (!in) {
ofstream out(Util::gserver_port_file.c_str());
if (out) {
out << port;
out.close();
chmod(Util::gserver_port_file.c_str(), 0644);
}
}
....
// fock子进程,通过子进程启动服务,当子进程因某些异常被中断后,主进程将自动创建新的子进程
pid_t fpid = fork();
if (fpid == 0) {
if (!Util::dir_exist("logs")) {
Util::create_dir("logs");
}
freopen(Util::gserver_log.c_str(), "a", stdout);
freopen(Util::gserver_log.c_str(), "a", stderr);
int status;
while (true) {
fpid = fork();
if (fpid == 0) {
// 初始化服务
Server server(port);
if (!server.createConnection()) {
cerr << Util::getTimeString() << "Failed to create connection at port " << port << '.' << endl;
return false;
}
cout << Util::getTimeString() << "Server started at port " << port << '.' << endl;
// 启动监听,开始接收客户端的请求
server.listen();
server.deleteConnection();
exit(0);
return true;
}
......
}
}
.....
}
通过-t
或--stop
命令停止服务
else if (mode == "-t" || mode == "--stop") {
if (isOnlyProcess(argv[0])) {
cerr << "gServer not running!" << endl;
return -1;
}
// 通过发送socket api请求(op=stop)到服务端,由服务端进行停服处理
if (stopServer()) {
return 0;
}
else {
return -1;
}
}
通过-r
或--restart
命令重启服务
else if (mode == "-r" || mode == "--restart") {
// 判断服务是否在运行
if (isOnlyProcess(argv[0])) {
cerr << "gServer not running!" << endl;
return -1;
}
// 停止服务
if (!stopServer()) {
return -1;
}
// 启动服务
if (startServer(false)) {
sleep(1);
if (isOnlyProcess(argv[0])) {
cerr << "Server stopped unexpectedly. Check for port conflicts!" << endl;
return -1;
}
return 0;
}
......
}
通过-p
或--printport
命令查看当前配置的端口
else if (mode == "-P" || mode == "--printport") {
unsigned short port = Socket::DEFAULT_CONNECT_PORT;
ifstream in(Util::gserver_port_file.c_str());
if (in) {
in >> port;
in.close();
}
cout << "Current connection port is " << port << '.' << endl;
unsigned short portSwap = 0;
ifstream inSwap(Util::gserver_port_swap.c_str());
if (inSwap) {
inSwap >> portSwap;
inSwap.close();
}
if (portSwap != 0) {
cout << "Connection port to be changed to " << portSwap << '.' << endl;
}
return 0;
}
通过-k
后--kill
命令强制停止服务,当通过-t
无法正常停服时,可使用改命令强制停止
else if (mode == "-k" || mode == "--kill") {
if (isOnlyProcess(argv[0])) {
cerr << "No process to kill!" << endl;
return -1;
}
execl("/usr/bin/killall", "killall", Util::getExactPath(argv[0]).c_str(), NULL);
return 0;
}
在前面介绍中,通过-s
或--start
参数启动服务后,将在startServer函数中fork一个子进程,并通过子进程完成服务的初始化和监听,等待客户端的连接请求。部分关键代码解析如下:
服务初始化并绑定端口
// 源码路径:Server/Server.cpp Server/Socket.cpp
bool Server::createConnection(){
bool flag;
// 调用Socket::create创建socket
flag = this->socket.create();
if (!flag){
cerr << Util::getTimeString() << "Cannot create socket.@Server::createConnection" << endl;
return false;
}
// 调用Socket::bind绑定端口
flag = this->socket.bind(this->connectionPort);
if (!flag)
{
cerr << Util::getTimeString() << "Cannot bind to port " << this->connectionPort << ". @Server::createConnection" << endl;
return false;
}
// 开启请求监听
flag = this->socket.listen();
if (!flag)
{
cerr << Util::getTimeString() << "Cannot listen to port" << this->connectionPort << ". @Server::createConnection" << endl;
return false;
}
return true;
}
监听连接,当有新的请求进来后,会创建一个子线程去处理请求,函数的代码片段如下:
void Server::listen(){
this->init();
Socket soc[this->connectionMaxNum];
int i = 0;
Socket new_server_socket;
while (true)
{
/**
* @brief Receive the stopServer signal.
*/
signal(SIGTERM, Server::stop_sigterm_handler);
cout << Util::getTimeString() << "Wait for connection..." << endl;
// 等待连接请求
this->socket.accept(new_server_socket);
cout << Util::getTimeString() << "Accept a new socket connection." << endl;
/**
* @brief Create a thread for a client socket.
*/
memcpy(&soc[i], &new_server_socket, sizeof(Socket));
sockThread* tid = new sockThread(soc[i++]);
tid->server = this;
tid->start();
}
}
// 子线程的关键代码段如下
void sockThread::run()
{
cout << Util::getTimeString() << "Thread:" << tid << " run\n";
server->handler(socket);
}
// 通过thread::detach()分离主线程
void sockThread::start()
{
TD = std::thread(&sockThread::run, this);
TD.detach();
}
在运行机制中介绍了通过创建子线程来处理每个请求,在sockThread::run()
函数中,请求最终将调用Server::handler(Socket& _socket)
方法进行统一处理并返回处理结果,部分代码片段如下:
void
Server::handler(Socket& _socket) {
int repeated_num = 0;
while (true) {
// 10次尝试仍未成功将关闭该次请求
if (repeated_num > 10)
break;
/**
* @brief Receive the command message from the client.
*/
std::string recv_cmd;
// 接收请求的数据
bool recv_return = _socket.recv(recv_cmd);
if (!recv_return)
{
cerr << Util::getTimeString() << "Receive command from client error.@Server::listen" << endl;
repeated_num++;
continue;
}
cout << Util::getTimeString() << "Received msg: " << recv_cmd << endl;
......
}
}
在正确接收到客户端请求的数据后,将对数据进行解析并调用对应的方法进行处理,socket api请求的数据格式为JSON字符串,格式如下:
{"op":"[op_type]","[param1]":"[value1]","[param2]":"[value2]"……}
op为指令参数,[paramx]为不同接口要求的参数,op参数对应的类型如下:
// Server/Operation.h
enum CommandType {
CMD_OTHER, /**< enum value other. */
CMD_TEST, /**< enum value test. */
CMD_LOGIN, /**< enum value login. */
CMD_BUILD, /**< enum value build. */
CMD_LOAD, /**< enum value load. */
CMD_UNLOAD, /**< enum value unload. */
CMD_QUERY, /**< enum value query. */
CMD_SHOW, /**< enum value show. */
CMD_STOP, /**< enum value stop. */
CMD_DROP, /**< enum value drop. */
CMD_CLOSE /**< enum value close. */
};
// Server/Server.cpp
bool Server::parser(std::string _raw_cmd, Operation& _ret_oprt) {
......
if (cmd == "test") { //心跳检测
_ret_oprt.setCommand(CMD_TEST);
}
if (cmd == "login") {//登录
_ret_oprt.setCommand(CMD_LOGIN);
......
}
else if (cmd == "build") {//创建
_ret_oprt.setCommand(CMD_BUILD);
......
}
else if (cmd == "load") {//加载
_ret_oprt.setCommand(CMD_LOAD);
......
}
else if (cmd == "unload") {//卸载
_ret_oprt.setCommand(CMD_UNLOAD);
......
}
else if (cmd == "query") {//查询
_ret_oprt.setCommand(CMD_QUERY);
......
}
else if (cmd == "show") {//查看库
_ret_oprt.setCommand(CMD_SHOW);
......
}
else if (cmd == "stop") {//停止服务
_ret_oprt.setCommand(CMD_STOP);
......
}
else if (cmd == "close") {//关闭连接
_ret_oprt.setCommand(CMD_CLOSE);
......
}
else if (cmd == "drop") {//删除库
_ret_oprt.setCommand(CMD_DROP);
......
}
......
}
通过op
参数来识别请求的接口,并调用对应的接口函数进行处理,部分代码片段如下:
void
Server::handler(Socket& _socket)
{
int repeated_num = 0;
while (true)
{
......
/**
* @brief Execute the specific command function.
*/
std::string ret_msg;
CommandType cmd_type = operation.getCommand();
bool _close = false;
switch (cmd_type)
{
case CMD_TEST: //心跳检测
{
ret_msg = "OK";
break;
}
case CMD_LOGIN://登录
{
std::string username = operation.getParameter("username");
std::string password = operation.getParameter("password");
this->login(username, password, _socket);
break;
}
case CMD_LOAD://加载库
{
std::string db_name = operation.getParameter("db_name");
this->load(db_name, _socket);
break;
}
case CMD_UNLOAD://卸载库
{
std::string db_name = operation.getParameter("db_name");
this->unload(db_name, _socket);
break;
}
case CMD_BUILD://创建库
{
std::string db_name = operation.getParameter("db_name");
std::string db_path = operation.getParameter("db_path");
this->build(db_name, db_path, _socket);
break;
}
case CMD_DROP://删除库
{
std::string db_name = operation.getParameter("db_name");
this->drop(db_name, _socket);
break;
}
case CMD_QUERY://查询
{
std::string db_name = operation.getParameter("db_name");
std::string sparql = operation.getParameter("sparql");
pthread_t timer = Server::start_timer();
if (timer == 0) {
cerr << Util::getTimeString() << "Failed to start timer." << endl;
}
this->query(db_name, sparql, _socket);
if (timer != 0 && !Server::stop_timer(timer)) {
cerr << Util::getTimeString() << "Failed to stop timer." << endl;
}
break;
}
case CMD_SHOW://查看库
{
this->show(_socket);
break;
}
case CMD_STOP://停止服务
{
this->stopServer(_socket);
_stop = true;
_close = true;
break;
}
case CMD_CLOSE://关闭连接
{
this->closeConnection(_socket);
_close = true;
break;
}
......
}
......
}
各接口函数的实现逻辑与ghttp模块的接口函数基本相同,这里将不再重复进行介绍,各接口的使用说明可查阅文章#gStore-weekly | gStore最新版本0.9.1之gServer详解(上)和#gStore-weekly | gStore最新版本0.9.1之gServer详解(下)。
本章节介绍了socket网络服务gserver模块,如何实现服务参数解析、服务运行机制以及请求的处理逻辑,建议在阅读的同时结合源码Main/gserver.cpp一起分析,会更容易理解。下一章将开始介绍gstore的安全机制系列源码。