1 /* We simply call the root header file "App.h", giving you uWS::App and uWS::SSLApp */
2 #include "App.h"
3
4 /* This is a simple WebSocket "sync" upgrade example.
5 * You may compile it with "WITH_OPENSSL=1 make" or with "make" */
6
main()7 int main() {
8 /* ws->getUserData returns one of these */
9 struct PerSocketData {
10 /* Define your user data */
11 int something;
12 };
13
14 /* Keep in mind that uWS::SSLApp({options}) is the same as uWS::App() when compiled without SSL support.
15 * You may swap to using uWS:App() if you don't need SSL */
16 uWS::SSLApp({
17 /* There are example certificates in uWebSockets.js repo */
18 .key_file_name = "../misc/key.pem",
19 .cert_file_name = "../misc/cert.pem",
20 .passphrase = "1234"
21 }).ws<PerSocketData>("/*", {
22 /* Settings */
23 .compression = uWS::SHARED_COMPRESSOR,
24 .maxPayloadLength = 16 * 1024,
25 .idleTimeout = 10,
26 .maxBackpressure = 1 * 1024 * 1024,
27 /* Handlers */
28 .upgrade = [](auto *res, auto *req, auto *context) {
29
30 /* You may read from req only here, and COPY whatever you need into your PerSocketData.
31 * PerSocketData is valid from .open to .close event, accessed with ws->getUserData().
32 * HttpRequest (req) is ONLY valid in this very callback, so any data you will need later
33 * has to be COPIED into PerSocketData here. */
34
35 /* Immediately upgrading without doing anything "async" before, is simple */
36 res->template upgrade<PerSocketData>({
37 /* We initialize PerSocketData struct here */
38 .something = 13
39 }, req->getHeader("sec-websocket-key"),
40 req->getHeader("sec-websocket-protocol"),
41 req->getHeader("sec-websocket-extensions"),
42 context);
43
44 /* If you don't want to upgrade you can instead respond with custom HTTP here,
45 * such as res->writeStatus(...)->writeHeader(...)->end(...); or similar.*/
46
47 /* Performing async upgrade, such as checking with a database is a little more complex;
48 * see UpgradeAsync example instead. */
49 },
50 .open = [](auto *ws) {
51 /* Open event here, you may access ws->getUserData() which points to a PerSocketData struct.
52 * Here we simply validate that indeed, something == 13 as set in upgrade handler. */
53 std::cout << "Something is: " << static_cast<PerSocketData *>(ws->getUserData())->something << std::endl;
54 },
55 .message = [](auto *ws, std::string_view message, uWS::OpCode opCode) {
56 /* We simply echo whatever data we get */
57 ws->send(message, opCode);
58 },
59 .drain = [](auto */*ws*/) {
60 /* Check ws->getBufferedAmount() here */
61 },
62 .ping = [](auto */*ws*/, std::string_view) {
63 /* You don't need to handle this one, we automatically respond to pings as per standard */
64 },
65 .pong = [](auto */*ws*/, std::string_view) {
66 /* You don't need to handle this one either */
67 },
68 .close = [](auto */*ws*/, int /*code*/, std::string_view /*message*/) {
69 /* You may access ws->getUserData() here, but sending or
70 * doing any kind of I/O with the socket is not valid. */
71 }
72 }).listen(9001, [](auto *listen_socket) {
73 if (listen_socket) {
74 std::cout << "Listening on port " << 9001 << std::endl;
75 }
76 }).run();
77 }
78