forked from guoxuanhan/NetServer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttpserver.cpp
More file actions
133 lines (115 loc) · 4.82 KB
/
httpserver.cpp
File metadata and controls
133 lines (115 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "httpserver.h"
#include <iostream>
#include <functional>
#include <memory>
#include "timermanager.h"
HttpServer::HttpServer(EventLoop *loop, const int port, const int iothreadnum, const int workerthreadnum)
: tcpserver_(loop, port, iothreadnum),
threadpool_(workerthreadnum)
{
tcpserver_.SetNewConnCallback(std::bind(&HttpServer::HandleNewConnection, this, std::placeholders::_1));
tcpserver_.SetMessageCallback(std::bind(&HttpServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2));
tcpserver_.SetSendCompleteCallback(std::bind(&HttpServer::HandleSendComplete, this, std::placeholders::_1));
tcpserver_.SetCloseCallback(std::bind(&HttpServer::HandleClose, this, std::placeholders::_1));
tcpserver_.SetErrorCallback(std::bind(&HttpServer::HandleError, this, std::placeholders::_1));
threadpool_.Start(); //工作线程池启动
TimerManager::GetTimerManagerInstance()->Start(); //HttpServer定时器管理器启动
}
HttpServer::~HttpServer()
{
}
void HttpServer::HandleNewConnection(const spTcpConnection& sptcpconn)
{
//std::string msg(s);
std::shared_ptr<HttpSession> sphttpsession = std::make_shared<HttpSession>(); //创建应用层会话
spTimer sptimer = std::make_shared<Timer>(5000, Timer::TimerType::TIMER_ONCE, std::bind(&TcpConnection::Shutdown, sptcpconn));
sptimer->Start();
//可以优化成无锁,放入conn里面就行
{
std::lock_guard <std::mutex> lock(mutex_);
httpsessionnlist_[sptcpconn] = sphttpsession;
timerlist_[sptcpconn] = sptimer;
}
}
void HttpServer::HandleMessage(const spTcpConnection& sptcpconn, std::string &msg)
{
std::shared_ptr<HttpSession> sphttpsession;
spTimer sptimer;
{
std::lock_guard <std::mutex> lock(mutex_);
sphttpsession = httpsessionnlist_[sptcpconn];
sptimer = timerlist_[sptcpconn];
}
sptimer->Adjust(5000, Timer::TimerType::TIMER_ONCE, std::bind(&TcpConnection::Shutdown, sptcpconn));
if(threadpool_.GetThreadNum() > 0)
{
//Bug20190320:多线程下,对象的声明周期管理问题,就像在这里,向线程池传入了phttpsession和ptcpconn,怎么知道其指向对象是否已经析构了呢?
//所以,需要采用智能指针来管理对象,替换原始指针
//线程池处理业务,处理完后投递回本IO线程执行send
//std::cout << "threadpool_.AddTask" << std::endl;
HttpRequestContext httprequestcontext;
std::string responsecontext;
bool result = sphttpsession->PraseHttpRequest(msg, httprequestcontext);
if(result == false)
{
sphttpsession->HttpError(400, "Bad request", httprequestcontext, responsecontext); //请求报文解析错误,报400
sptcpconn->Send(responsecontext);
return;
}
sptcpconn->SetAsyncProcessing(true);
threadpool_.AddTask([=]() {
//HttpRequestContext req = httprequestcontext;
std::string responsemsg;
sphttpsession->HttpProcess(httprequestcontext, responsemsg);
sptcpconn->Send(responsemsg); //任务已经处理完成,执行跨线程调度,即回调
if(!sphttpsession->KeepAlive())
{
//短连接,可以告诉框架层数据发完就可以关掉TCP连接,不过这里注释掉,还是交给客户端主动关闭吧
//sptcpconn->HandleClose();
}
});
}
else
{
//没有开启业务线程池,业务计算直接在IO线程执行
HttpRequestContext httprequestcontext;
std::string responsecontext;
bool result = sphttpsession->PraseHttpRequest(msg, httprequestcontext);
if(result == false)
{
sphttpsession->HttpError(400, "Bad request", httprequestcontext, responsecontext); //请求报文解析错误,报400
sptcpconn->Send(responsecontext);
return;
}
sphttpsession->HttpProcess(httprequestcontext, responsecontext);
sptcpconn->Send(responsecontext);
if(!sphttpsession->KeepAlive())
{
//短连接,可以告诉框架层数据发完就可以关掉TCP连接,不过这里注释掉,还是交给客户端主动关闭吧
//sptcpconn->HandleClose();
}
}
}
void HttpServer::HandleSendComplete(const spTcpConnection& sptcpconn)
{
}
void HttpServer::HandleClose(const spTcpConnection& sptcpconn)
{
{
std::lock_guard <std::mutex> lock(mutex_);
httpsessionnlist_.erase(sptcpconn);
timerlist_.erase(sptcpconn);
}
}
void HttpServer::HandleError(const spTcpConnection& sptcpconn)
{
{
std::lock_guard <std::mutex> lock(mutex_);
httpsessionnlist_.erase(sptcpconn);
timerlist_.erase(sptcpconn);
}
}
void HttpServer::Start()
{
tcpserver_.Start();
}