forked from IronsDu/brynet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWebBinaryProxy.cpp
More file actions
125 lines (103 loc) · 5.07 KB
/
WebBinaryProxy.cpp
File metadata and controls
125 lines (103 loc) · 5.07 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
#include <iostream>
#include <string>
#include <thread>
#include <brynet/net/SocketLibFunction.h>
#include <brynet/net/http/HttpService.h>
#include <brynet/net/http/HttpFormat.h>
#include <brynet/net/http/WebSocketFormat.h>
#include <brynet/net/Connector.h>
using namespace std;
using namespace brynet;
using namespace brynet::net;
int main(int argc, char **argv)
{
if (argc != 4)
{
fprintf(stderr, "Usage: <listen port> <backend ip> <backend port>");
exit(-1);
}
int bindPort = atoi(argv[1]);
string backendIP = argv[2];
int backendPort = atoi(argv[3]);
auto tcpService = TcpService::Create();
tcpService->startWorkerThread(std::thread::hardware_concurrency());
auto asyncConnector = AsyncConnector::Create();
asyncConnector->startWorkerThread();
auto listenThread = ListenThread::Create(false,
"0.0.0.0",
bindPort,
[tcpService, asyncConnector, backendIP, backendPort](TcpSocket::Ptr socket) {
auto enterCallback = [tcpService, asyncConnector, backendIP, backendPort](const TcpConnection::Ptr& session) {
session->setUD(static_cast<int64_t>(1));
std::shared_ptr<TcpConnection::Ptr> shareBackendSession = std::make_shared<TcpConnection::Ptr>(nullptr);
std::shared_ptr<std::vector<string>> cachePacket = std::make_shared<std::vector<std::string>>();
auto enterCallback = [tcpService, session, shareBackendSession, cachePacket](TcpSocket::Ptr socket) {
auto enterCallback = [=](const TcpConnection::Ptr& backendSession) {
auto ud = brynet::net::cast<int64_t>(session->getUD());
if (*ud == -1) /*if http client already close*/
{
backendSession->postDisConnect();
return;
}
*shareBackendSession = backendSession;
for (auto& p : *cachePacket)
{
backendSession->send(p.c_str(), p.size());
}
cachePacket->clear();
backendSession->setDisConnectCallback([=](const TcpConnection::Ptr& backendSession) {
*shareBackendSession = nullptr;
auto ud = brynet::net::cast<int64_t>(session->getUD());
if (*ud != -1)
{
session->postDisConnect();
}
});
backendSession->setDataCallback([=](const char* buffer,
size_t size) {
/* recieve data from backend server, then send to http client */
session->send(buffer, size);
return size;
});
};
tcpService->addTcpConnection(std::move(socket),
brynet::net::TcpService::AddSocketOption::AddEnterCallback(enterCallback),
brynet::net::TcpService::AddSocketOption::WithMaxRecvBufferSize(32 * 1024));
};
/* new connect to backend server */
asyncConnector->asyncConnect({
AsyncConnector::ConnectOptions::WithAddr(backendIP.c_str(), backendPort),
AsyncConnector::ConnectOptions::WithTimeout(std::chrono::seconds(10)),
AsyncConnector::ConnectOptions::WithCompletedCallback(enterCallback) });
session->setDataCallback([=](const char* buffer, size_t size) {
TcpConnection::Ptr backendSession = *shareBackendSession;
if (backendSession == nullptr)
{
/*cache it*/
cachePacket->push_back(std::string(buffer, size));
}
else
{
/* receive data from http client, then send to backend server */
backendSession->send(buffer, size);
}
return size;
});
session->setDisConnectCallback([=](const TcpConnection::Ptr& session) {
/*if http client close, then close it's backend server */
TcpConnection::Ptr backendSession = *shareBackendSession;
if (backendSession != nullptr)
{
backendSession->postDisConnect();
}
session->setUD(-1);
});
};
tcpService->addTcpConnection(std::move(socket),
brynet::net::TcpService::AddSocketOption::AddEnterCallback(enterCallback),
brynet::net::TcpService::AddSocketOption::WithMaxRecvBufferSize(32 * 1024));
});
// listen for front http client
listenThread->startListen();
std::cin.get();
}