Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "SimpleChatServer.h"
00008 #include <Wt/WServer>
00009
00010 #include <iostream>
00011 #include <boost/lexical_cast.hpp>
00012
00013 using namespace Wt;
00014
00015 const WString ChatEvent::formattedHTML(const WString& user) const
00016 {
00017 switch (type_) {
00018 case Login:
00019 return "<span class='chat-info'>" + user_ + " joined.</span>";
00020 case Logout:
00021 return "<span class='chat-info'>"
00022 + ((user == user_) ? "You" : user_)
00023 + " logged out.</span>";
00024 case Rename:
00025 return "<span class='chat-info'>"
00026 + ((user == data_ || user == user_) ?
00027 "You are" : (user_ + " is")) + " now known as "
00028 + data_ + ".</span>";
00029 case Message:{
00030 WString result;
00031
00032 result = WString("<span class='")
00033 + ((user == user_) ? "chat-self" : "chat-user")
00034 + "'>" + user_ + ":</span>";
00035
00036 if (message_.toUTF8().find(user.toUTF8()) != std::string::npos)
00037 return result + "<span class='chat-highlight'>" + message_ + "</span>";
00038 else
00039 return result + message_;
00040 }
00041 default:
00042 return "";
00043 }
00044 }
00045
00046
00047 SimpleChatServer::SimpleChatServer(WServer& server)
00048 : server_(server)
00049 { }
00050
00051 bool SimpleChatServer::connect(Client *client,
00052 const ChatEventCallback& handleEvent)
00053 {
00054 boost::recursive_mutex::scoped_lock lock(mutex_);
00055
00056 if (clients_.count(client) == 0) {
00057 ClientInfo clientInfo;
00058
00059 clientInfo.sessionId = WApplication::instance()->sessionId();
00060 clientInfo.eventCallback = handleEvent;
00061
00062 clients_[client] = clientInfo;
00063
00064 return true;
00065 } else
00066 return false;
00067 }
00068
00069 bool SimpleChatServer::disconnect(Client *client)
00070 {
00071 boost::recursive_mutex::scoped_lock lock(mutex_);
00072
00073 return clients_.erase(client) == 1;
00074 }
00075
00076 bool SimpleChatServer::login(const WString& user)
00077 {
00078 boost::recursive_mutex::scoped_lock lock(mutex_);
00079
00080 if (users_.find(user) == users_.end()) {
00081 users_.insert(user);
00082
00083 postChatEvent(ChatEvent(ChatEvent::Login, user));
00084
00085 return true;
00086 } else
00087 return false;
00088 }
00089
00090 void SimpleChatServer::logout(const WString& user)
00091 {
00092 boost::recursive_mutex::scoped_lock lock(mutex_);
00093
00094 UserSet::iterator i = users_.find(user);
00095
00096 if (i != users_.end()) {
00097 users_.erase(i);
00098
00099 postChatEvent(ChatEvent(ChatEvent::Logout, user));
00100 }
00101 }
00102
00103 bool SimpleChatServer::changeName(const WString& user, const WString& newUser)
00104 {
00105 if (user == newUser)
00106 return true;
00107
00108 boost::recursive_mutex::scoped_lock lock(mutex_);
00109
00110 UserSet::iterator i = users_.find(user);
00111
00112 if (i != users_.end()) {
00113 if (users_.count(newUser) == 0) {
00114 users_.erase(i);
00115 users_.insert(newUser);
00116
00117 postChatEvent(ChatEvent(ChatEvent::Rename, user, newUser));
00118
00119 return true;
00120 } else
00121 return false;
00122 } else
00123 return false;
00124 }
00125
00126 WString SimpleChatServer::suggestGuest()
00127 {
00128 boost::recursive_mutex::scoped_lock lock(mutex_);
00129
00130 for (int i = 1;; ++i) {
00131 std::string s = "guest " + boost::lexical_cast<std::string>(i);
00132 WString ss = s;
00133
00134 if (users_.find(ss) == users_.end())
00135 return ss;
00136 }
00137 }
00138
00139 void SimpleChatServer::sendMessage(const WString& user, const WString& message)
00140 {
00141 postChatEvent(ChatEvent(user, message));
00142 }
00143
00144 void SimpleChatServer::postChatEvent(const ChatEvent& event)
00145 {
00146 boost::recursive_mutex::scoped_lock lock(mutex_);
00147
00148 WApplication *app = WApplication::instance();
00149
00150 for (ClientMap::const_iterator i = clients_.begin(); i != clients_.end();
00151 ++i) {
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 if (app && app->sessionId() == i->second.sessionId)
00163 i->second.eventCallback(event);
00164 else
00165 server_.post(i->second.sessionId,
00166 boost::bind(i->second.eventCallback, event));
00167 }
00168 }
00169
00170 SimpleChatServer::UserSet SimpleChatServer::users()
00171 {
00172 boost::recursive_mutex::scoped_lock lock(mutex_);
00173
00174 UserSet result = users_;
00175
00176 return result;
00177 }
00178