mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Fixed chat server to work with new api fixes #4
This commit is contained in:
@@ -27,31 +27,154 @@
|
||||
|
||||
#include "chat.hpp"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
using websocketchat::chat_handler;
|
||||
using websocketpp::session_ptr;
|
||||
|
||||
|
||||
void chat_handler::validate(websocketpp::session_ptr client) {
|
||||
void chat_handler::validate(session_ptr client) {
|
||||
std::stringstream err;
|
||||
|
||||
// We only know about the chat resource
|
||||
if (client->get_request() != "/chat") {
|
||||
err << "Request for unknown resource " << client->get_request();
|
||||
throw(handshake_error(err.str(),404));
|
||||
throw(websocketpp::handshake_error(err.str(),404));
|
||||
}
|
||||
|
||||
// Require specific origin example
|
||||
if (client->get_origin() != "http://zaphoyd.com") {
|
||||
err << "Request from unrecognized origin: " << client->get_origin();
|
||||
throw(handshake_error(err.str(),403));
|
||||
throw(websocketpp::handshake_error(err.str(),403));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void connect(session_ptr client) {
|
||||
void chat_handler::connect(session_ptr client) {
|
||||
std::cout << "client " << client << " joined the lobby." << std::endl;
|
||||
m_connections.insert(client);
|
||||
|
||||
// send user list to all clients
|
||||
// send signon message from server to all other clients.
|
||||
m_connections.insert(std::pair<session_ptr,std::string>(client,get_con_id(client)));
|
||||
|
||||
// send user list and signon message to all clients
|
||||
send_to_all(serialize_state());
|
||||
client->send(encode_message("server","Welcome, use the /alias command to set a name, /help for a list of other commands."));
|
||||
send_to_all(encode_message("server",m_connections[client]+" has joined the chat."));
|
||||
}
|
||||
|
||||
void chat_handler::disconnect(session_ptr client,uint16_t status,const std::string &reason) {
|
||||
std::map<session_ptr,std::string>::iterator it = m_connections.find(client);
|
||||
|
||||
if (it == m_connections.end()) {
|
||||
// this client has already disconnected, we can ignore this.
|
||||
// this happens during certain types of disconnect where there is a
|
||||
// deliberate "soft" disconnection preceeding the "hard" socket read
|
||||
// fail or disconnect ack message.
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "client " << client << " left the lobby." << std::endl;
|
||||
|
||||
m_connections.erase(it);
|
||||
|
||||
// send user list and signoff message to all clients
|
||||
send_to_all(serialize_state());
|
||||
send_to_all(encode_message("server",m_connections[client]+" has left the chat."));
|
||||
}
|
||||
|
||||
void chat_handler::message(session_ptr client,const std::string &msg) {
|
||||
std::cout << "message from client " << client << ": " << msg << std::endl;
|
||||
|
||||
|
||||
|
||||
// check for special command messages
|
||||
if (msg == "/help") {
|
||||
// print command list
|
||||
client->send(encode_message("server","avaliable commands:<br /> /help - show this help<br /> /alias foo - set alias to foo",false));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.substr(0,7) == "/alias ") {
|
||||
std::string response;
|
||||
std::string alias;
|
||||
|
||||
if (msg.size() == 7) {
|
||||
response = "You must enter an alias.";
|
||||
client->send(encode_message("server",response));
|
||||
return;
|
||||
} else {
|
||||
alias = msg.substr(7);
|
||||
}
|
||||
|
||||
// store alias
|
||||
response = m_connections[client] + " is now known as "+alias;
|
||||
|
||||
m_connections[client] = alias;
|
||||
|
||||
// set alias
|
||||
send_to_all(serialize_state());
|
||||
send_to_all(encode_message("server",response));
|
||||
return;
|
||||
}
|
||||
|
||||
// catch other slash commands
|
||||
if (msg[0] == '/') {
|
||||
client->send(encode_message("server","unrecognized command"));
|
||||
return;
|
||||
}
|
||||
|
||||
// create JSON message to send based on msg
|
||||
send_to_all(encode_message(m_connections[client],msg));
|
||||
}
|
||||
|
||||
// {"type":"participants","value":[<participant>,...]}
|
||||
std::string chat_handler::serialize_state() {
|
||||
std::stringstream s;
|
||||
|
||||
s << "{\"type\":\"participants\",\"value\":[";
|
||||
|
||||
std::map<session_ptr,std::string>::iterator it;
|
||||
|
||||
for (it = m_connections.begin(); it != m_connections.end(); it++) {
|
||||
s << "\"" << (*it).second << "\"";
|
||||
if (++it != m_connections.end()) {
|
||||
s << ",";
|
||||
}
|
||||
it--;
|
||||
}
|
||||
|
||||
s << "]}";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
// {"type":"msg","sender":"<sender>","value":"<msg>" }
|
||||
std::string chat_handler::encode_message(std::string sender,std::string msg,bool escape) {
|
||||
std::stringstream s;
|
||||
|
||||
// escape JSON characters
|
||||
boost::algorithm::replace_all(msg,"\\","\\\\");
|
||||
boost::algorithm::replace_all(msg,"\"","\\\"");
|
||||
|
||||
// escape HTML characters
|
||||
if (escape) {
|
||||
boost::algorithm::replace_all(msg,"&","&");
|
||||
boost::algorithm::replace_all(msg,"<","<");
|
||||
boost::algorithm::replace_all(msg,">",">");
|
||||
}
|
||||
|
||||
s << "{\"type\":\"msg\",\"sender\":\"" << sender
|
||||
<< "\",\"value\":\"" << msg << "\"}";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
std::string chat_handler::get_con_id(session_ptr s) {
|
||||
std::stringstream endpoint;
|
||||
endpoint << s->socket().remote_endpoint();
|
||||
return endpoint.str();
|
||||
}
|
||||
|
||||
void chat_handler::send_to_all(std::string data) {
|
||||
std::map<session_ptr,std::string>::iterator it;
|
||||
for (it = m_connections.begin(); it != m_connections.end(); it++) {
|
||||
(*it).first->send(data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user