|
|
@ -3,21 +3,56 @@ |
|
|
|
#include <string> |
|
|
|
|
|
|
|
#include <lib/libwebsockets.h> |
|
|
|
#include <json_spirit/json_spirit.h> |
|
|
|
#include "websockets.h" |
|
|
|
|
|
|
|
int uid = 0; |
|
|
|
std::map<int, std::string> people_online; |
|
|
|
namespace js = json_spirit; |
|
|
|
|
|
|
|
js::Object get_object(std::string const & in){ |
|
|
|
js::Value value; |
|
|
|
js::read(in, value); |
|
|
|
return value.getObject(); |
|
|
|
} |
|
|
|
|
|
|
|
// NOTE: we cannot use C++ ctors and dtors, because it will be allocated by libwebsockets (= C lib)
|
|
|
|
int uid = 0; |
|
|
|
struct User { |
|
|
|
unsigned int index; |
|
|
|
unsigned int index{0}; |
|
|
|
std::string name{"Guest"}; |
|
|
|
|
|
|
|
int width{0}; |
|
|
|
int height{0}; |
|
|
|
|
|
|
|
static User from_json(const js::Object& obj){ |
|
|
|
User ret; |
|
|
|
#define in(x, f) ret.x = obj.at(#x).f() |
|
|
|
in(name, getString); |
|
|
|
in(width, getInt); |
|
|
|
in(height, getInt); |
|
|
|
#undef in |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
js::Object to_json() const { |
|
|
|
js::Object obj; |
|
|
|
#define out(x) obj[#x] = x |
|
|
|
out(name); |
|
|
|
out(width); |
|
|
|
out(height); |
|
|
|
#undef out |
|
|
|
return obj; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// unfortunately libwebsockets own the user thingy
|
|
|
|
std::map<unsigned int, User*> people_online; |
|
|
|
|
|
|
|
|
|
|
|
websockets::TestProtocol<User> default_protocol{ |
|
|
|
// connection established
|
|
|
|
[](User& user){ |
|
|
|
user.name = "Unknown guest"; |
|
|
|
user.index = uid++; |
|
|
|
people_online[user.index] = ""; |
|
|
|
people_online[user.index] = &user; |
|
|
|
}, |
|
|
|
// connection closed
|
|
|
|
[](User& user){ |
|
|
@ -26,17 +61,47 @@ websockets::TestProtocol<User> default_protocol{ |
|
|
|
// write (will always come after receive)
|
|
|
|
[](User& user) -> std::string{ |
|
|
|
std::string string_to_send = "Other People:"; |
|
|
|
for(auto x : people_online) if(x.first != user.index) string_to_send += " " + x.second; |
|
|
|
for(auto x : people_online) if(x.second != &user) string_to_send += " " + x.second->name; |
|
|
|
return string_to_send; |
|
|
|
}, |
|
|
|
// receive
|
|
|
|
[](User& user, std::string in){ |
|
|
|
people_online[user.index] = in; |
|
|
|
try{ |
|
|
|
user = User::from_json(get_object(in)); |
|
|
|
} catch(std::exception& e) { |
|
|
|
throw websockets::runtime_error(e.what()); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct Empty{ |
|
|
|
int x; |
|
|
|
}; |
|
|
|
|
|
|
|
websockets::TestProtocol<Empty> observer_protocol{ |
|
|
|
// connection established
|
|
|
|
[](Empty& user){}, |
|
|
|
// connection closed
|
|
|
|
[](Empty& user){}, |
|
|
|
// write (will always come after receive)
|
|
|
|
[](Empty& user) -> std::string{ |
|
|
|
js::Array array; |
|
|
|
for(auto x : people_online){ |
|
|
|
array.push_back(x.second->to_json()); |
|
|
|
} |
|
|
|
js::Value value(array); |
|
|
|
std::cout << "OUTPUT JSON: " << write(value, js::remove_trailing_zeros) << std::endl; |
|
|
|
return write(value); |
|
|
|
}, |
|
|
|
// receive
|
|
|
|
[](Empty& user, std::string in){ |
|
|
|
std::cout << "INPUT: " << in << std::endl; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
static libwebsocket_protocols protocols[] = { |
|
|
|
WSstandard_protocol("default", default_protocol), |
|
|
|
WSstandard_protocol("observer", observer_protocol), |
|
|
|
{ NULL, NULL, 0 } // end of list
|
|
|
|
}; |
|
|
|
|
|
|
|