ana/apps/chat/server.cpp

Go to the documentation of this file.
00001 /* $Id: server.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 
00003 /**
00004  * @file
00005  * @brief Server side chat application. Example for the ana project.
00006  *
00007  * ana: Asynchronous Network API.
00008  * Copyright (C) 2010 - 2012 Guillermo Biset.
00009  *
00010  * This file is part of the ana project.
00011  *
00012  * System:         ana
00013  * Language:       C++
00014  *
00015  * Author:         Guillermo Biset
00016  * E-Mail:         billybiset AT gmail DOT com
00017  *
00018  * ana is free software: you can redistribute it and/or modify
00019  * it under the terms of the GNU General Public License as published by
00020  * the Free Software Foundation, either version 2 of the License, or
00021  * (at your option) any later version.
00022  *
00023  * ana is distributed in the hope that it will be useful,
00024  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00025  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026  * GNU General Public License for more details.
00027  *
00028  * You should have received a copy of the GNU General Public License
00029  * along with ana.  If not, see <http://www.gnu.org/licenses/>.
00030  *
00031  */
00032 
00033 #include <iostream>
00034 #include <sstream>
00035 
00036 #include "ana.hpp"
00037 
00038 using namespace ana;
00039 
00040 const port DEFAULT_PORT = "30303";
00041 
00042 class ChatServer : public listener_handler,
00043                    public send_handler,
00044                    public connection_handler
00045 {
00046     public:
00047         ChatServer() :
00048             server_( ana::server::create() ),
00049             names_()
00050         {
00051         }
00052 
00053         void run(port pt)
00054         {
00055             server_->set_connection_handler( this );
00056 
00057             server_->set_listener_handler( this );
00058 
00059             server_->run(pt);
00060 
00061 //             server_->set_timeouts(ana::FixedTime, ana::time::milliseconds(1));
00062 
00063             std::cout << "Server running, Enter to quit." << std::endl;
00064 
00065             std::string s;
00066             std::getline(std::cin, s); //yes, i've seen better code :)
00067         }
00068 
00069         ~ChatServer()
00070         {
00071             delete server_;
00072         }
00073     private:
00074 
00075         virtual void handle_connect(ana::error_code error, net_id client)
00076         {
00077             if (! error)
00078             {
00079                 std::stringstream ss;
00080                 ss << "Server: User " << client << " has joined from "
00081                    << server_->ip_address( client ) << ".";
00082                 server_->send_all_except(client, ana::buffer( ss.str() ), this);
00083             }
00084         }
00085 
00086         virtual void handle_disconnect(ana::error_code error, net_id client)
00087         {
00088             std::stringstream ss;
00089             ss << names_[client] << " disconnected.";
00090             server_->send_all_except(client, ana::buffer( ss.str() ), this);
00091             names_.erase(client);
00092         }
00093 
00094         virtual void handle_send(ana::error_code error, net_id client, ana::operation_id id)
00095         {
00096             if ( error )
00097                 std::cerr << "Error sending to client " << client << ". Timeout?" << std::endl;
00098         }
00099 
00100         std::string get_name(const std::string& msg)
00101         {
00102             size_t pos = msg.find(" ");
00103 
00104             return msg.substr(pos+1);
00105         }
00106 
00107         void parse_command(net_id client, const std::string& msg)
00108         {
00109             switch (msg[1]) //Lame
00110             {
00111                 case 'n': //assume name command
00112                             names_[client] = get_name(msg);
00113                             break;
00114                 case 'w': //assume who command
00115                             std::stringstream ss;
00116                             ss << "Connected clients: \n";
00117 
00118                             std::map<net_id, std::string>::iterator it;
00119                             for(it = names_.begin(); it != names_.end(); ++it)
00120                                 ss << "    " << it->second << "\n";
00121 
00122                             server_->send_one(client, ana::buffer( ss.str() ), this);
00123                             break;
00124             }
00125         }
00126 
00127         virtual void handle_receive( ana::error_code          error,
00128                                      net_id                   client,
00129                                      ana::read_buffer         buffer)
00130         {
00131             if (! error)
00132             {
00133                 std::string msg = buffer->string();
00134 
00135                 if (msg.empty())
00136                     std::cout << "Received empty buffer. Size: " << buffer->size() << "\n";
00137                 else if (msg[0] == '/')
00138                     parse_command(client, msg);
00139                 else
00140                 {
00141                     std::stringstream ss;
00142                     ss << names_[client] << " : " << msg;
00143                     server_->send_all_except(client, ana::buffer( ss.str() ), this);
00144                 }
00145             }
00146             else
00147                 handle_disconnect(error, client);
00148         }
00149 
00150         server*                       server_;
00151         std::map<net_id, std::string> names_;
00152 };
00153 
00154 int main(int argc, char **argv)
00155 {
00156     std::cout << "Use " << argv[0] << " port_number to run on a specific port (default: "
00157               << DEFAULT_PORT << ".)\n\n";
00158 
00159     port pt(DEFAULT_PORT);
00160 
00161     if ( argc > 1 )
00162         pt = argv[1];
00163 
00164     ChatServer server;
00165     server.run(pt);
00166 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue May 22 2012 01:03:39 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs