blob: 2a8823afe689e22b2fce9e1690e3376f7f17c8ca [file] [log] [blame]
Austin Schuh24adb6b2015-09-06 17:37:40 -07001// Copyright (c) 2013, Matt Godbolt
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// Redistributions of source code must retain the above copyright notice, this
8// list of conditions and the following disclaimer.
9//
10// Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24// POSSIBILITY OF SUCH DAMAGE.
25
26// An extraordinarily simple test which presents a web page with some buttons.
27// Clicking on the numbered button increments the number, which is visible to
28// other connected clients. WebSockets are used to do this: by the rather
29// suspicious means of sending raw JavaScript commands to be executed on other
30// clients.
31
32#include "seasocks/PrintfLogger.h"
33#include "seasocks/Server.h"
34#include "seasocks/StringUtil.h"
35#include "seasocks/WebSocket.h"
36#include "seasocks/util/Json.h"
37
38#include <cstring>
39#include <iostream>
40#include <memory>
41#include <set>
42#include <sstream>
43#include <string>
44
45using namespace seasocks;
46using namespace std;
47
48class MyHandler: public WebSocket::Handler {
49public:
50 MyHandler(Server* server) : _server(server), _currentValue(0) {
51 setValue(1);
52 }
53
54 virtual void onConnect(WebSocket* connection) {
55 _connections.insert(connection);
56 connection->send(_currentSetValue.c_str());
57 cout << "Connected: " << connection->getRequestUri()
58 << " : " << formatAddress(connection->getRemoteAddress())
59 << endl;
60 cout << "Credentials: " << *(connection->credentials()) << endl;
61 }
62
63 virtual void onData(WebSocket* connection, const char* data) {
64 if (0 == strcmp("die", data)) {
65 _server->terminate();
66 return;
67 }
68 if (0 == strcmp("close", data)) {
69 cout << "Closing.." << endl;
70 connection->close();
71 cout << "Closed." << endl;
72 return;
73 }
74
75 int value = atoi(data) + 1;
76 if (value > _currentValue) {
77 setValue(value);
78 for (auto connection : _connections) {
79 connection->send(_currentSetValue.c_str());
80 }
81 }
82 }
83
84 virtual void onDisconnect(WebSocket* connection) {
85 _connections.erase(connection);
86 cout << "Disconnected: " << connection->getRequestUri()
87 << " : " << formatAddress(connection->getRemoteAddress())
88 << endl;
89 }
90
91private:
92 set<WebSocket*> _connections;
93 Server* _server;
94 int _currentValue;
95 string _currentSetValue;
96
97 void setValue(int value) {
98 _currentValue = value;
99 _currentSetValue = makeExecString("set", _currentValue);
100 }
101};
102
103int main(int argc, const char* argv[]) {
104 shared_ptr<Logger> logger(new PrintfLogger(Logger::DEBUG));
105
106 Server server(logger);
107
108 shared_ptr<MyHandler> handler(new MyHandler(&server));
109 server.addWebSocketHandler("/ws", handler);
110 server.serve("src/ws_test_web", 9090);
111 return 0;
112}