Wt examples 3.1.10
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes
SimpleChatServer Class Reference

A simple chat server. More...

#include <SimpleChatServer.h>

List of all members.

Classes

struct  UserInfo

Public Types

typedef std::set< Wt::WStringUserSet
 Typedef for a collection of user names.

Public Member Functions

 SimpleChatServer (Wt::WServer &server)
 Create a new chat server.
bool login (const Wt::WString &user, const ChatEventCallback &handleEvent)
 Try to login with given user name.
void logout (const Wt::WString &user)
 Logout from the server.
bool changeName (const Wt::WString &user, const Wt::WString &newUser)
 Changes the name.
Wt::WString suggestGuest ()
 Get a suggestion for a guest user name.
void sendMessage (const Wt::WString &user, const Wt::WString &message)
 Send a message on behalve of a user.
UserSet users ()
 Get the users currently logged in.

Private Types

typedef std::map< Wt::WString,
UserInfo
UserMap

Private Member Functions

void postChatEvent (const ChatEvent &event)

Private Attributes

Wt::WServerserver_
boost::recursive_mutex mutex_
UserMap users_

Detailed Description

A simple chat server.

Definition at line 82 of file SimpleChatServer.h.


Member Typedef Documentation

typedef std::map<Wt::WString, UserInfo> SimpleChatServer::UserMap [private]

Definition at line 126 of file SimpleChatServer.h.

Typedef for a collection of user names.

Definition at line 114 of file SimpleChatServer.h.


Constructor & Destructor Documentation

SimpleChatServer::SimpleChatServer ( Wt::WServer server)

Create a new chat server.

Definition at line 47 of file SimpleChatServer.C.

  : server_(server)
{ }

Member Function Documentation

bool SimpleChatServer::changeName ( const Wt::WString user,
const Wt::WString newUser 
)

Changes the name.

Definition at line 83 of file SimpleChatServer.C.

{
  if (user == newUser)
    return true;

  boost::recursive_mutex::scoped_lock lock(mutex_);
  
  UserMap::iterator i = users_.find(user);

  if (i != users_.end()) {
    if (users_.find(newUser) == users_.end()) {
      UserInfo info = i->second;
      users_.erase(i);
      users_[newUser] = info;

      postChatEvent(ChatEvent(ChatEvent::Rename, user, newUser));

      return true;
    } else
      return false;
  } else
    return false;
}
bool SimpleChatServer::login ( const Wt::WString user,
const ChatEventCallback handleEvent 
)

Try to login with given user name.

Returns false if the login was not successfull. The passed callback method is posted to when a new chat event is received.

Definition at line 51 of file SimpleChatServer.C.

{
  boost::recursive_mutex::scoped_lock lock(mutex_);
  
  if (users_.find(user) == users_.end()) {
    UserInfo userInfo;
    userInfo.sessionId = WApplication::instance()->sessionId();
    userInfo.eventCallback = handleEvent;

    users_[user] = userInfo;

    postChatEvent(ChatEvent(ChatEvent::Login, user));

    return true;
  } else
    return false;
}
void SimpleChatServer::logout ( const Wt::WString user)

Logout from the server.

Definition at line 70 of file SimpleChatServer.C.

{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  UserMap::iterator i = users_.find(user);

  if (i != users_.end()) {
    users_.erase(i);

    postChatEvent(ChatEvent(ChatEvent::Logout, user));
  }
}
void SimpleChatServer::postChatEvent ( const ChatEvent event) [private]

Definition at line 125 of file SimpleChatServer.C.

{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  WApplication *app = WApplication::instance();

  for (UserMap::const_iterator i = users_.begin(); i != users_.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));
  }
}
void SimpleChatServer::sendMessage ( const Wt::WString user,
const Wt::WString message 
)

Send a message on behalve of a user.

Definition at line 120 of file SimpleChatServer.C.

{
  postChatEvent(ChatEvent(user, message));
}
WString SimpleChatServer::suggestGuest ( )

Get a suggestion for a guest user name.

Definition at line 107 of file SimpleChatServer.C.

{
  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;
  }
}
SimpleChatServer::UserSet SimpleChatServer::users ( )

Get the users currently logged in.

Definition at line 150 of file SimpleChatServer.C.

{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  UserSet result;
  for (UserMap::const_iterator i = users_.begin(); i != users_.end(); ++i)
    result.insert(i->first);

  return result;
}

Member Data Documentation

boost::recursive_mutex SimpleChatServer::mutex_ [private]

Definition at line 129 of file SimpleChatServer.h.

Definition at line 128 of file SimpleChatServer.h.

Definition at line 130 of file SimpleChatServer.h.


The documentation for this class was generated from the following files:

Generated on Wed Jul 27 2011 for the C++ Web Toolkit (Wt) by doxygen 1.7.4