Skip to content

Commit 13dca20

Browse files
committed
Wangle Echo Server & Client
1 parent 43761c5 commit 13dca20

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed

examples/wangle/echo/BUILD

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
licenses(["notice"])
2+
3+
cc_binary(
4+
name = "echo_server",
5+
visibility = ["//visibility:public"],
6+
srcs = ["EchoServer.cpp"],
7+
deps = [
8+
"//third_party/wangle:wangle",
9+
"//third_party/folly:folly",
10+
"//third_party/glog:glog"
11+
]
12+
)
13+
14+
cc_binary(
15+
name = "echo_client",
16+
visibility = ["//visibility:public"],
17+
srcs = ["EchoClient.cpp"],
18+
deps = [
19+
"//third_party/wangle:wangle",
20+
"//third_party/folly:folly",
21+
"//third_party/glog:glog"
22+
]
23+
)
24+
25+

examples/wangle/echo/EchoClient.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <gflags/gflags.h>
2+
#include <iostream>
3+
#include <wangle/bootstrap/ClientBootstrap.h>
4+
#include <wangle/channel/AsyncSocketHandler.h>
5+
#include <wangle/channel/EventBaseHandler.h>
6+
#include <wangle/codec/LineBasedFrameDecoder.h>
7+
#include <wangle/codec/StringCodec.h>
8+
9+
using namespace folly;
10+
using namespace wangle;
11+
12+
DEFINE_int32(port, 8080, "echo server port");
13+
DEFINE_string(host, "::1", "echo server address");
14+
15+
typedef Pipeline<folly::IOBufQueue&, std::string> EchoPipeline;
16+
17+
// the handler for receiving messages back from the server
18+
class EchoHandler : public HandlerAdapter<std::string> {
19+
public:
20+
virtual void read(Context* ctx, std::string msg) override {
21+
std::cout << "received back: " << msg;
22+
}
23+
virtual void readException(Context* ctx, exception_wrapper e) override {
24+
std::cout << exceptionStr(e) << std::endl;
25+
close(ctx);
26+
}
27+
virtual void readEOF(Context* ctx) override {
28+
std::cout << "EOF received :(" << std::endl;
29+
close(ctx);
30+
}
31+
};
32+
33+
// chains the handlers together to define the response pipeline
34+
class EchoPipelineFactory : public PipelineFactory<EchoPipeline> {
35+
public:
36+
EchoPipeline::Ptr newPipeline(std::shared_ptr<AsyncTransportWrapper> sock) {
37+
auto pipeline = EchoPipeline::create();
38+
pipeline->addBack(AsyncSocketHandler(sock));
39+
pipeline->addBack(
40+
EventBaseHandler()); // ensure we can write from any thread
41+
pipeline->addBack(LineBasedFrameDecoder(8192, false));
42+
pipeline->addBack(StringCodec());
43+
pipeline->addBack(EchoHandler());
44+
pipeline->finalize();
45+
return pipeline;
46+
}
47+
};
48+
49+
int main(int argc, char** argv) {
50+
gflags::ParseCommandLineFlags(&argc, &argv, true);
51+
52+
ClientBootstrap<EchoPipeline> client;
53+
client.group(std::make_shared<wangle::IOThreadPoolExecutor>(1));
54+
client.pipelineFactory(std::make_shared<EchoPipelineFactory>());
55+
auto pipeline = client.connect(SocketAddress(FLAGS_host, FLAGS_port)).get();
56+
57+
try {
58+
while (true) {
59+
std::string line;
60+
std::getline(std::cin, line);
61+
if (line == "") {
62+
break;
63+
}
64+
65+
pipeline->write(line + "\r\n").get();
66+
if (line == "bye") {
67+
pipeline->close();
68+
break;
69+
}
70+
}
71+
} catch (const std::exception& e) {
72+
std::cout << exceptionStr(e) << std::endl;
73+
}
74+
75+
return 0;
76+
}
77+

examples/wangle/echo/EchoServer.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include <gflags/gflags.h>
2+
#include <wangle/bootstrap/ServerBootstrap.h>
3+
#include <wangle/channel/AsyncSocketHandler.h>
4+
#include <wangle/codec/LineBasedFrameDecoder.h>
5+
#include <wangle/codec/StringCodec.h>
6+
7+
using namespace folly;
8+
using namespace wangle;
9+
10+
DEFINE_int32(port, 8080, "echo server port");
11+
12+
typedef Pipeline<IOBufQueue&, std::string> EchoPipeline;
13+
14+
// the main logic of our echo server; receives a string and writes it straight
15+
// back
16+
class EchoHandler : public HandlerAdapter<std::string> {
17+
public:
18+
virtual void read(Context* ctx, std::string msg) override {
19+
std::cout << "handling " << msg << std::endl;
20+
write(ctx, msg + "\r\n");
21+
}
22+
};
23+
24+
// where we define the chain of handlers for each messeage received
25+
class EchoPipelineFactory : public PipelineFactory<EchoPipeline> {
26+
public:
27+
EchoPipeline::Ptr newPipeline(std::shared_ptr<AsyncTransportWrapper> sock) {
28+
auto pipeline = EchoPipeline::create();
29+
pipeline->addBack(AsyncSocketHandler(sock));
30+
pipeline->addBack(LineBasedFrameDecoder(8192));
31+
pipeline->addBack(StringCodec());
32+
pipeline->addBack(EchoHandler());
33+
pipeline->finalize();
34+
return pipeline;
35+
}
36+
};
37+
38+
int main(int argc, char** argv) {
39+
gflags::ParseCommandLineFlags(&argc, &argv, true);
40+
41+
ServerBootstrap<EchoPipeline> server;
42+
server.childPipeline(std::make_shared<EchoPipelineFactory>());
43+
server.bind(FLAGS_port);
44+
server.waitForStop();
45+
46+
return 0;
47+
}
48+

examples/wangle/echo/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Wangle Examples
2+
3+
This directory provides examples of using the Wangle Echo Server.
4+
5+
## Compiling
6+
7+
Echo Server:
8+
9+
`bazel build //examples/wangle/echo:echo_server`
10+
11+
Echo Client:
12+
13+
`bazel build //examples/wangle/echo:echo_client`

third_party/wangle/BUILD

+18
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ cc_library(
8484
]
8585
)
8686

87+
cc_library(
88+
name = "codec",
89+
visibility = ["//visibility:public"],
90+
includes = [
91+
"upstream",
92+
],
93+
hdrs = glob(["upstream/wangle/codec/*.h"]),
94+
srcs = [
95+
"upstream/wangle/codec/LineBasedFrameDecoder.cpp",
96+
"upstream/wangle/codec/LengthFieldPrepender.cpp",
97+
"upstream/wangle/codec/LengthFieldBasedFrameDecoder.cpp"
98+
],
99+
deps = [
100+
":channel"
101+
]
102+
)
103+
87104
# Disabled because dependings on boost/thread
88105
#
89106
# cc_test(
@@ -119,5 +136,6 @@ cc_library(
119136
":channel",
120137
":concurrent",
121138
":ssl",
139+
":codec"
122140
]
123141
)

0 commit comments

Comments
 (0)