-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathwebsocket_server.cpp
138 lines (129 loc) · 5.14 KB
/
websocket_server.cpp
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
134
135
136
137
138
#include <co_async/co_async.hpp>
#include <co_async/std.hpp>
using namespace co_async;
using namespace std::literals;
static auto index_html = R"html(<!DOCTYPE html>
<html>
<head>
<title>WebSocket 客户端</title>
<meta charset="UTF-8">
</head>
<body>
<div id="container">
<h3>WebSocket 客户端</h3>
<p>小彭老师自主研发的一款</p>
<input type="text" id="content" placeholder="输入你的消息..." autocomplete="off"/>
<button id="send">发送</button>
<p>客户端日志:</p>
<textarea disabled id="log" rows="20" cols="50" autocomplete="off"></textarea>
</div>
<script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script>
<script>
function log() {
function addIndent(nSpaces) {
var strOutput = '';
for(var i = 0; i < nSpaces; i++) {
strOutput += ' ';
}
return strOutput;
}
function parseObjToStr(oObject, nLevel) {
if (typeof oObject !== 'string') {
var strOutput = "{\n";
nLevel = nLevel || 0;
for (var oEl in oObject) {
if (typeof oObject[oEl] === 'object'
|| Object.prototype.toString.call(oObject[oEl]) === '[object Array]') {
strOutput += addIndent(nLevel) + oEl + " = ";
strOutput += parseObjToStr(oObject[oEl], nLevel+1) + ",\n";
} else {
var str = oObject[oEl].toString();
if (typeof oObject[oEl] === 'string') {
str = "'" + str.replaceAll("'", "\\'").replaceAll('\n', '\\n') + "'";
} else {
str = str.replaceAll('\n', '\n' + addIndent(nLevel));
}
strOutput += addIndent(nLevel) + oEl + " = " + str + ",\n";
}
}
strOutput += addIndent(nLevel) + "}";
return strOutput;
} else {
return oObject;
}
}
var content = "";
for (var i = 0; i < arguments.length; i++) {
content += parseObjToStr(arguments[i], 1) + " ";
}
$('#log').val($('#log').val() + content + "\n");
}
$(document).ready(function() {
var ws = new WebSocket("ws://127.0.0.1:8080/");
ws.onopen = function() {
log("连接成功!");
};
ws.onmessage = function (evt) {
var response = evt.data;
log("收到消息:", response);
};
ws.onclose = function() {
log("连接已关闭");
};
ws.onerror = function(err) {
log("发生错误:", err);
};
$('#send').click(function() {
var content = $('#content').val();
log("正在发送数据", content);
ws.send(content);
});
});
</script>
</body>
</html>)html"sv;
static Task<Expected<>> amain(std::string addr) {
co_await co_await stdio().putline("正在监听: "s + addr);
auto listener = co_await co_await listener_bind(co_await AddressResolver()
.host(addr).resolve_one());
HTTPServer server;
server.route("GET", "/", [](HTTPServer::IO &io) -> Task<Expected<>> {
if (auto ws = co_await websocket_server(io)) {
// 是升级的 ws:// 请求
co_await co_await stdio().putline("连接成功"sv);
ws->on_message([&] (std::string const &message) -> Task<Expected<>> {
co_await co_await stdio().putline("收到消息: "s + message);
co_await co_await ws->send("收到啦!"s + message);
co_return {};
});
ws->on_close([&] () -> Task<Expected<>> {
co_await co_await stdio().putline("正在关闭连接"sv);
co_return {};
});
ws->on_pong([&] (std::chrono::steady_clock::duration dt) -> Task<Expected<>> {
co_await co_await stdio().putline("网络延迟: "s + to_string(
std::chrono::duration_cast<std::chrono::milliseconds>(dt).count()) + "ms"s);
co_return {};
});
co_await co_await ws->start();
co_return {};
} else {
// 是普通 http:// 请求
co_await co_await HTTPServerUtils::make_ok_response(io, index_html);
co_return {};
}
});
while (true) {
if (auto income = co_await listener_accept(listener)) {
co_spawn(server.handle_http(std::move(*income)));
}
}
}
int main(int argc, char **argv) {
std::string addr = "http://127.0.0.1:8080";
if (argc > 1) {
addr = argv[1];
}
co_main(amain(addr));
return 0;
}