chat server example updated to latest API

This commit is contained in:
Peter Thorson
2012-02-24 08:03:47 -06:00
parent 3ec229c223
commit 986905e80c
4 changed files with 59 additions and 57 deletions

View File

@@ -1,13 +1,17 @@
CFLAGS = -O2
LDFLAGS =
BOOST_LIB_PATH ?= /usr/local/lib
BOOST_INCLUDE_PATH ?= /usr/local/include
CPP11 ?=
CFLAGS = -Wall -O2 $(CPP11) -I$(BOOST_INCLUDE_PATH)
LDFLAGS = -L$(BOOST_LIB_PATH)
CXX ?= c++
SHARED ?= "1"
ifeq ($(SHARED), 1)
LDFLAGS := $(LDFLAGS) -lboost_system -lboost_date_time -lwebsocketpp
LDFLAGS := $(LDFLAGS) -lboost_system -lboost_date_time -lboost_program_options -lboost_thread -lpthread -lwebsocketpp
else
LDFLAGS := $(LDFLAGS) -lboost_system -lboost_date_time -lboost_regex -lboost_random -lboost_program_options ../../libwebsocketpp.a
LDFLAGS := $(LDFLAGS) ../../libwebsocketpp.a $(BOOST_LIB_PATH)/libboost_system.a $(BOOST_LIB_PATH)/libboost_date_time.a $(BOOST_LIB_PATH)/libboost_regex.a $(BOOST_LIB_PATH)/libboost_thread.a -lpthread
endif
chat_server: chat_server.o chat.o

View File

@@ -29,39 +29,38 @@
#include <boost/algorithm/string/replace.hpp>
using websocketchat::chat_server_handler;
using websocketpp::session::server_session_ptr;
using namespace websocketchat;
//using chat_server_handler::connection_ptr;
void chat_server_handler::validate(server_session_ptr session) {
void chat_server_handler::validate(connection_ptr con) {
std::stringstream err;
// We only know about the chat resource
if (session->get_resource() != "/chat") {
err << "Request for unknown resource " << session->get_resource();
if (con->get_resource() != "/chat") {
err << "Request for unknown resource " << con->get_resource();
throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::NOT_FOUND));
}
// Require specific origin example
if (session->get_origin() != "http://zaphoyd.com") {
err << "Request from unrecognized origin: " << session->get_origin();
if (con->get_origin() != "http://zaphoyd.com") {
err << "Request from unrecognized origin: " << con->get_origin();
throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::FORBIDDEN));
}
}
void chat_server_handler::on_open(server_session_ptr session) {
std::cout << "client " << session << " joined the lobby." << std::endl;
m_connections.insert(std::pair<server_session_ptr,std::string>(session,get_con_id(session)));
void chat_server_handler::on_open(connection_ptr con) {
std::cout << "client " << con << " joined the lobby." << std::endl;
m_connections.insert(std::pair<connection_ptr,std::string>(con,get_con_id(con)));
// send user list and signon message to all clients
send_to_all(serialize_state());
session->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[session]+" has joined the chat."));
con->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[con]+" has joined the chat."));
}
void chat_server_handler::on_close(server_session_ptr session) {
std::map<server_session_ptr,std::string>::iterator it = m_connections.find(session);
void chat_server_handler::on_close(connection_ptr con) {
std::map<connection_ptr,std::string>::iterator it = m_connections.find(con);
if (it == m_connections.end()) {
// this client has already disconnected, we can ignore this.
@@ -71,7 +70,7 @@ void chat_server_handler::on_close(server_session_ptr session) {
return;
}
std::cout << "client " << session << " left the lobby." << std::endl;
std::cout << "client " << con << " left the lobby." << std::endl;
const std::string alias = it->second;
m_connections.erase(it);
@@ -81,31 +80,35 @@ void chat_server_handler::on_close(server_session_ptr session) {
send_to_all(encode_message("server",alias+" has left the chat."));
}
void chat_server_handler::on_message(server_session_ptr session,websocketpp::utf8_string_ptr msg) {
std::cout << "message from client " << session << ": " << *msg << std::endl;
void chat_server_handler::on_message(connection_ptr con, message_ptr msg) {
if (msg->get_opcode() != websocketpp::frame::opcode::TEXT) {
return;
}
std::cout << "message from client " << con << ": " << msg->get_payload() << std::endl;
// check for special command messages
if (*msg == "/help") {
if (msg->get_payload() == "/help") {
// print command list
session->send(encode_message("server","avaliable commands:<br />&nbsp;&nbsp;&nbsp;&nbsp;/help - show this help<br />&nbsp;&nbsp;&nbsp;&nbsp;/alias foo - set alias to foo",false));
con->send(encode_message("server","avaliable commands:<br />&nbsp;&nbsp;&nbsp;&nbsp;/help - show this help<br />&nbsp;&nbsp;&nbsp;&nbsp;/alias foo - set alias to foo",false));
return;
}
if (msg->substr(0,7) == "/alias ") {
if (msg->get_payload().substr(0,7) == "/alias ") {
std::string response;
std::string alias;
if (msg->size() == 7) {
if (msg->get_payload().size() == 7) {
response = "You must enter an alias.";
session->send(encode_message("server",response));
con->send(encode_message("server",response));
return;
} else {
alias = msg->substr(7);
alias = msg->get_payload().substr(7);
}
response = m_connections[session] + " is now known as "+alias;
response = m_connections[con] + " is now known as "+alias;
// store alias pre-escaped so we don't have to do this replacing every time this
// user sends a message
@@ -119,7 +122,7 @@ void chat_server_handler::on_message(server_session_ptr session,websocketpp::utf
boost::algorithm::replace_all(alias,"<","&lt;");
boost::algorithm::replace_all(alias,">","&gt;");
m_connections[session] = alias;
m_connections[con] = alias;
// set alias
send_to_all(serialize_state());
@@ -128,13 +131,13 @@ void chat_server_handler::on_message(server_session_ptr session,websocketpp::utf
}
// catch other slash commands
if ((*msg)[0] == '/') {
session->send(encode_message("server","unrecognized command"));
if ((msg->get_payload())[0] == '/') {
con->send(encode_message("server","unrecognized command"));
return;
}
// create JSON message to send based on msg
send_to_all(encode_message(m_connections[session],*msg));
send_to_all(encode_message(m_connections[con],msg->get_payload()));
}
// {"type":"participants","value":[<participant>,...]}
@@ -143,7 +146,7 @@ std::string chat_server_handler::serialize_state() {
s << "{\"type\":\"participants\",\"value\":[";
std::map<server_session_ptr,std::string>::iterator it;
std::map<connection_ptr,std::string>::iterator it;
for (it = m_connections.begin(); it != m_connections.end(); it++) {
s << "\"" << (*it).second << "\"";
@@ -179,14 +182,15 @@ std::string chat_server_handler::encode_message(std::string sender,std::string m
return s.str();
}
std::string chat_server_handler::get_con_id(server_session_ptr s) {
std::string chat_server_handler::get_con_id(connection_ptr con) {
std::stringstream endpoint;
endpoint << s->get_endpoint();
//endpoint << con->get_endpoint();
endpoint << con;
return endpoint.str();
}
void chat_server_handler::send_to_all(std::string data) {
std::map<server_session_ptr,std::string>::iterator it;
std::map<connection_ptr,std::string>::iterator it;
for (it = m_connections.begin(); it != m_connections.end(); it++) {
(*it).first->send(data);
}

View File

@@ -39,41 +39,35 @@
// {"type":"participants","value":[<participant>,...]}
#include "../../src/websocketpp.hpp"
#include "../../src/interfaces/session.hpp"
#include <boost/shared_ptr.hpp>
#include <map>
#include <string>
#include <vector>
using websocketpp::session::server_session_ptr;
using websocketpp::session::server_handler;
using websocketpp::server;
namespace websocketchat {
class chat_server_handler : public server_handler {
class chat_server_handler : public server::handler {
public:
void validate(server_session_ptr session);
void validate(connection_ptr con);
// add new connection to the lobby
void on_open(server_session_ptr session);
void on_open(connection_ptr con);
// someone disconnected from the lobby, remove them
void on_close(server_session_ptr session);
void on_close(connection_ptr con);
void on_message(server_session_ptr session,websocketpp::utf8_string_ptr msg);
// lobby will ignore binary messages
void on_message(server_session_ptr session,websocketpp::binary_string_ptr data) {}
void on_message(connection_ptr con, message_ptr msg);
private:
std::string serialize_state();
std::string encode_message(std::string sender,std::string msg,bool escape = true);
std::string get_con_id(server_session_ptr s);
std::string get_con_id(connection_ptr con);
void send_to_all(std::string data);
// list of outstanding connections
std::map<server_session_ptr,std::string> m_connections;
std::map<connection_ptr,std::string> m_connections;
};
typedef boost::shared_ptr<chat_server_handler> chat_server_handler_ptr;

View File

@@ -32,8 +32,8 @@
#include <iostream>
using boost::asio::ip::tcp;
using namespace websocketchat;
using websocketpp::server;
int main(int argc, char* argv[]) {
short port = 9003;
@@ -45,14 +45,14 @@ int main(int argc, char* argv[]) {
try {
// create an instance of our handler
server_handler_ptr default_handler(new chat_server_handler());
server::handler::ptr handler(new chat_server_handler());
// create a server that listens on port `port` and uses our handler
websocketpp::basic_server_ptr server(new websocketpp::basic_server(port,default_handler));
server endpoint(handler);
server->elog().set_levels(websocketpp::log::elevel::DEVEL,websocketpp::log::elevel::FATAL);
endpoint.elog().set_levels(websocketpp::log::elevel::DEVEL,websocketpp::log::elevel::FATAL);
server->alog().set_level(websocketpp::log::alevel::ALL);
endpoint.alog().set_level(websocketpp::log::alevel::ALL);
// setup server settings
// Chat server should only be receiving small text messages, reduce max
@@ -62,7 +62,7 @@ int main(int argc, char* argv[]) {
std::cout << "Starting chat server on port " << port << std::endl;
server->run();
endpoint.listen(port);
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}