Multi-user gravity beats for Sound of Science 2013 (server)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 

116 lines
3.2 KiB

#include <memory>
#include <string>
#include <stdexcept>
#include <lib/libwebsockets.h>
#include "websockets.h"
#include "json.h"
#include "json_ext.h"
#include "basics.h"
#include "app.h"
std::unique_ptr<App> app;
using namespace websockets;
websockets::TestProtocol<User> default_protocol{
// connection established
[](User& user, basic_websocket_info){
app->login(user);
std::cout << "New user!\n";
},
// connection closed
[](User& user, basic_websocket_info){
app->logout(user);
std::cout << "User left: " << &user << ": " << user.name << std::endl;
},
// write (will always come after receive)
[](User& user, basic_websocket_info) -> std::string{
js::Object ret;
if(user.update_lines){
if(app->uberclient){
ret["lines"] = vector_to_json(app->offline_sim.lines);
} else {
ret["lines"] = vector_to_json(app->online_sim.lines, [](AbstractLine const & l){return cheap_line_type(l);});
}
user.update_lines = false;
} else {
if(app->uberclient){
ret["balls"] = vector_to_json(app->offline_sim.balls);
} else {
ret["balls"] = vector_to_json(app->online_sim.sim.balls, [](ball_type const & b){return cheap_ball_type(b);});
}
}
return write_json(ret);
},
// receive
[](User& user, std::string in, basic_websocket_info binfo){
try{
auto object = parse_json(in).getObject();
auto command = object["command"];
if(command == "add line"){
app->add_line(from_json<cheap_line_type>(object["data"]));
std::cout << "Line from: " << &user << ": " << user.name << std::endl;
request_write(binfo);
} else if (command == "update user") {
user = from_json<IncomingPacket>(object["data"]);
std::cout << "Updated user: " << &user << ": " << user.name << std::endl;
} else if (command == "poll") {
request_write(binfo);
}
} catch(std::exception& e) {
throw websockets::runtime_error(e.what());
}
}
};
websockets::TestProtocol<Empty> uberclient_protocol{
// connection established
[](Empty& user, basic_websocket_info binfo){
std::cout << "uberclient connected!\n";
app->uberclient_connected(binfo);
},
// connection closed
[](Empty& user, basic_websocket_info binfo){
std::cout << "uberclient left!\n";
app->uberclient_disconnected(binfo);
},
// write (will always come after receive)
[](Empty& user, basic_websocket_info) -> std::string{
static int i = 0;
return std::to_string(i++);
},
// receive
[](Empty& user, std::string in, basic_websocket_info){
auto object = parse_json(in).getObject();
if(object.count("lines")){
app->offline_sim.lines.clear();
auto lines = object["lines"];
for(auto&& js : lines.getArray()){
app->offline_sim.lines.push_back(from_json<cheap_line_type>(js));
}
}
if(object.count("balls")){
app->offline_sim.balls.clear();
auto balls = object["balls"];
for(auto&& js : balls.getArray()){
app->offline_sim.balls.push_back(from_json<cheap_ball_type>(js));
}
}
}
};
int main(int argc, char **argv){
app.reset(new App);
libwebsocket_protocols protocols[] = {
WSstandard_protocol("default", default_protocol),
WSstandard_protocol("uberclient", uberclient_protocol),
{ NULL, NULL, 0 } // end of list
};
return websockets::default_main(argc, argv, protocols, []{app->update();});
}