/usr/lib/Wt/examples/simplechat/SimpleChatServer.C is in witty-examples 3.3.0-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | /*
* Copyright (C) 2008 Emweb bvba, Heverlee, Belgium.
*
* See the LICENSE file for terms of use.
*/
#include "SimpleChatServer.h"
#include <Wt/WServer>
#include <iostream>
#include <boost/lexical_cast.hpp>
using namespace Wt;
const WString ChatEvent::formattedHTML(const WString& user,
TextFormat format) const
{
switch (type_) {
case Login:
return WString::fromUTF8("<span class='chat-info'>")
+ WWebWidget::escapeText(user_) + " joined.</span>";
case Logout:
return WString::fromUTF8("<span class='chat-info'>")
+ ((user == user_) ?
WString::fromUTF8("You") :
WWebWidget::escapeText(user_))
+ " logged out.</span>";
case Rename:
return "<span class='chat-info'>"
+ ((user == data_ || user == user_) ?
"You are" :
(WWebWidget::escapeText(user_) + " is"))
+ " now known as " + WWebWidget::escapeText(data_) + ".</span>";
case Message:{
WString result;
result = WString("<span class='")
+ ((user == user_) ?
"chat-self" :
"chat-user")
+ "'>" + WWebWidget::escapeText(user_) + ":</span>";
WString msg
= (format == XHTMLText ? message_ : WWebWidget::escapeText(message_));
if (message_.toUTF8().find(user.toUTF8()) != std::string::npos)
return result + "<span class='chat-highlight'>" + msg + "</span>";
else
return result + msg;
}
default:
return "";
}
}
SimpleChatServer::SimpleChatServer(WServer& server)
: server_(server)
{ }
bool SimpleChatServer::connect(Client *client,
const ChatEventCallback& handleEvent)
{
boost::recursive_mutex::scoped_lock lock(mutex_);
if (clients_.count(client) == 0) {
ClientInfo clientInfo;
clientInfo.sessionId = WApplication::instance()->sessionId();
clientInfo.eventCallback = handleEvent;
clients_[client] = clientInfo;
return true;
} else
return false;
}
bool SimpleChatServer::disconnect(Client *client)
{
boost::recursive_mutex::scoped_lock lock(mutex_);
return clients_.erase(client) == 1;
}
bool SimpleChatServer::login(const WString& user)
{
boost::recursive_mutex::scoped_lock lock(mutex_);
if (users_.find(user) == users_.end()) {
users_.insert(user);
postChatEvent(ChatEvent(ChatEvent::Login, user));
return true;
} else
return false;
}
void SimpleChatServer::logout(const WString& user)
{
boost::recursive_mutex::scoped_lock lock(mutex_);
UserSet::iterator i = users_.find(user);
if (i != users_.end()) {
users_.erase(i);
postChatEvent(ChatEvent(ChatEvent::Logout, user));
}
}
bool SimpleChatServer::changeName(const WString& user, const WString& newUser)
{
if (user == newUser)
return true;
boost::recursive_mutex::scoped_lock lock(mutex_);
UserSet::iterator i = users_.find(user);
if (i != users_.end()) {
if (users_.count(newUser) == 0) {
users_.erase(i);
users_.insert(newUser);
postChatEvent(ChatEvent(ChatEvent::Rename, user, newUser));
return true;
} else
return false;
} else
return false;
}
WString SimpleChatServer::suggestGuest()
{
boost::recursive_mutex::scoped_lock lock(mutex_);
for (int i = 1;; ++i) {
std::string s = "guest " + boost::lexical_cast<std::string>(i);
WString ss = s;
if (users_.find(ss) == users_.end())
return ss;
}
}
void SimpleChatServer::sendMessage(const WString& user, const WString& message)
{
postChatEvent(ChatEvent(user, message));
}
void SimpleChatServer::postChatEvent(const ChatEvent& event)
{
boost::recursive_mutex::scoped_lock lock(mutex_);
WApplication *app = WApplication::instance();
for (ClientMap::const_iterator i = clients_.begin(); i != clients_.end();
++i) {
/*
* If the user corresponds to the current application, we directly
* call the call back method. This avoids an unnecessary delay for
* the update to the user causing the event.
*
* For other uses, we post it to their session. By posting the
* event, we avoid dead-lock scenarios, race conditions, and
* delivering the event to a session that is just about to be
* terminated.
*/
if (app && app->sessionId() == i->second.sessionId)
i->second.eventCallback(event);
else
server_.post(i->second.sessionId,
boost::bind(i->second.eventCallback, event));
}
}
SimpleChatServer::UserSet SimpleChatServer::users()
{
boost::recursive_mutex::scoped_lock lock(mutex_);
UserSet result = users_;
return result;
}
|