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::login(const WString& user,
00052 const ChatEventCallback& handleEvent)
00053 {
00054 boost::recursive_mutex::scoped_lock lock(mutex_);
00055
00056 if (users_.find(user) == users_.end()) {
00057 UserInfo userInfo;
00058 userInfo.sessionId = WApplication::instance()->sessionId();
00059 userInfo.eventCallback = handleEvent;
00060
00061 users_[user] = userInfo;
00062
00063 postChatEvent(ChatEvent(ChatEvent::Login, user));
00064
00065 return true;
00066 } else
00067 return false;
00068 }
00069
00070 void SimpleChatServer::logout(const WString& user)
00071 {
00072 boost::recursive_mutex::scoped_lock lock(mutex_);
00073
00074 UserMap::iterator i = users_.find(user);
00075
00076 if (i != users_.end()) {
00077 users_.erase(i);
00078
00079 postChatEvent(ChatEvent(ChatEvent::Logout, user));
00080 }
00081 }
00082
00083 bool SimpleChatServer::changeName(const WString& user, const WString& newUser)
00084 {
00085 if (user == newUser)
00086 return true;
00087
00088 boost::recursive_mutex::scoped_lock lock(mutex_);
00089
00090 UserMap::iterator i = users_.find(user);
00091
00092 if (i != users_.end()) {
00093 if (users_.find(newUser) == users_.end()) {
00094 UserInfo info = i->second;
00095 users_.erase(i);
00096 users_[newUser] = info;
00097
00098 postChatEvent(ChatEvent(ChatEvent::Rename, user, newUser));
00099
00100 return true;
00101 } else
00102 return false;
00103 } else
00104 return false;
00105 }
00106
00107 WString SimpleChatServer::suggestGuest()
00108 {
00109 boost::recursive_mutex::scoped_lock lock(mutex_);
00110
00111 for (int i = 1;; ++i) {
00112 std::string s = "guest " + boost::lexical_cast<std::string>(i);
00113 WString ss = s;
00114
00115 if (users_.find(ss) == users_.end())
00116 return ss;
00117 }
00118 }
00119
00120 void SimpleChatServer::sendMessage(const WString& user, const WString& message)
00121 {
00122 postChatEvent(ChatEvent(user, message));
00123 }
00124
00125 void SimpleChatServer::postChatEvent(const ChatEvent& event)
00126 {
00127 boost::recursive_mutex::scoped_lock lock(mutex_);
00128
00129 WApplication *app = WApplication::instance();
00130
00131 for (UserMap::const_iterator i = users_.begin(); i != users_.end(); ++i) {
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 if (app && app->sessionId() == i->second.sessionId)
00143 i->second.eventCallback(event);
00144 else
00145 server_.post(i->second.sessionId,
00146 boost::bind(i->second.eventCallback, event));
00147 }
00148 }
00149
00150 SimpleChatServer::UserSet SimpleChatServer::users()
00151 {
00152 boost::recursive_mutex::scoped_lock lock(mutex_);
00153
00154 UserSet result;
00155 for (UserMap::const_iterator i = users_.begin(); i != users_.end(); ++i)
00156 result.insert(i->first);
00157
00158 return result;
00159 }
00160