summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/demo/Glacier2/README4
-rw-r--r--cpp/demo/Glacier2/callback/SessionI.h8
-rw-r--r--cpp/demo/Glacier2/chat/Chat.ice31
-rwxr-xr-xcpp/demo/Glacier2/chat/ChatSessionI.cpp99
-rwxr-xr-xcpp/demo/Glacier2/chat/ChatSessionI.h51
-rwxr-xr-xcpp/demo/Glacier2/chat/Client.cpp159
-rw-r--r--cpp/demo/Glacier2/chat/README16
-rwxr-xr-xcpp/demo/Glacier2/chat/Server.cpp73
-rwxr-xr-xcpp/demo/Glacier2/chat/chatC.dsp153
-rwxr-xr-xcpp/demo/Glacier2/chat/chatS.dsp161
-rw-r--r--cpp/demo/Glacier2/chat/config54
-rw-r--r--cpp/demo/Glacier2/chat/config.glacier2116
-rw-r--r--cpp/demo/Glacier2/chat/config.server15
13 files changed, 940 insertions, 0 deletions
diff --git a/cpp/demo/Glacier2/README b/cpp/demo/Glacier2/README
index 5d86320b6cb..97ea63a6fbe 100644
--- a/cpp/demo/Glacier2/README
+++ b/cpp/demo/Glacier2/README
@@ -13,3 +13,7 @@ Demos in this directory:
Illustrates how to allow a server to call back into a client
via a Glacier2 connection.
+
+- chat
+
+ A very simply chat server that illustrates the Glacier2 session API.
diff --git a/cpp/demo/Glacier2/callback/SessionI.h b/cpp/demo/Glacier2/callback/SessionI.h
index 461825b139e..3829c456f5d 100644
--- a/cpp/demo/Glacier2/callback/SessionI.h
+++ b/cpp/demo/Glacier2/callback/SessionI.h
@@ -21,6 +21,14 @@ public:
virtual bool checkPermissions(const std::string&, const std::string&, std::string&, const Ice::Current&) const;
};
+bool
+DummyPermissionsVerifierI::checkPermissions(const string& userId, const string& password, string&,
+ const Current&) const
+{
+ cout << "verified user `" << userId << "' with password `" << password << "'" << endl;
+ return true;
+}
+
class SessionI : public Glacier2::Session
{
public:
diff --git a/cpp/demo/Glacier2/chat/Chat.ice b/cpp/demo/Glacier2/chat/Chat.ice
new file mode 100644
index 00000000000..d10290813c2
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/Chat.ice
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CHAT_ICE
+#define CHAT_ICE
+
+#include <Glacier2/Session.ice>
+
+module Demo
+{
+
+interface ChatCallback
+{
+ void message(string data);
+};
+
+interface ChatSession extends Glacier2::Session
+{
+ void setCallback(ChatCallback* callback);
+ void say(string data);
+};
+
+};
+
+#endif
diff --git a/cpp/demo/Glacier2/chat/ChatSessionI.cpp b/cpp/demo/Glacier2/chat/ChatSessionI.cpp
new file mode 100755
index 00000000000..64452734c53
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/ChatSessionI.cpp
@@ -0,0 +1,99 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <ChatSessionI.h>
+
+using namespace std;
+using namespace Demo;
+
+ChatRoomMembers::ChatRoomMembers()
+{
+}
+
+void
+ChatRoomMembers::add(const ChatCallbackPrx& callback)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ _members.push_back(callback);
+}
+
+void
+ChatRoomMembers::remove(const ChatCallbackPrx& callback)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ list<ChatCallbackPrx>::iterator p = find(_members.begin(), _members.end(), callback);
+ if(p != _members.end())
+ {
+ _members.erase(p);
+ }
+}
+
+void
+ChatRoomMembers::message(const string& data)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ list<ChatCallbackPrx>::iterator p = _members.begin();
+ while(p != _members.end())
+ {
+ try
+ {
+ (*p)->message(data);
+ }
+ catch(const Ice::LocalException&)
+ {
+ p = _members.erase(p);
+ continue;
+ }
+ ++p;
+ }
+}
+
+ChatSessionI::ChatSessionI(const ChatRoomMembersPtr& members, const string& userId) :
+ _members(members),
+ _userId(userId),
+ _destroy(false)
+{
+ _members->message(_userId + " has entered the chat room.");
+}
+
+void
+ChatSessionI::setCallback(const ChatCallbackPrx& callback, const Ice::Current& current)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ if(!_callback)
+ {
+ _callback = callback;
+ _members->add(callback);
+ }
+}
+
+void
+ChatSessionI::say(const string& data, const Ice::Current&)
+{
+ _members->message(_userId + " says: " + data);
+}
+
+void
+ChatSessionI::destroy(const Ice::Current& current)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ if(!_destroy)
+ {
+ _destroy = true;
+ if(_callback)
+ {
+ _members->remove(_callback);
+ _callback = 0;
+ }
+ current.adapter->remove(current.id);
+ _members->message(_userId + " has left the chat room.");
+ }
+}
+
diff --git a/cpp/demo/Glacier2/chat/ChatSessionI.h b/cpp/demo/Glacier2/chat/ChatSessionI.h
new file mode 100755
index 00000000000..fa7fa7c874c
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/ChatSessionI.h
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CHAT_SESSION_I_H
+#define CHAT_SESSION_I_H
+
+#include <Chat.h>
+
+#include <list>
+
+class ChatRoomMembers : public IceUtil::Mutex, public IceUtil::Shared
+{
+public:
+
+ ChatRoomMembers();
+
+ void add(const ::Demo::ChatCallbackPrx&);
+ void remove(const ::Demo::ChatCallbackPrx&);
+ void message(const std::string&);
+
+private:
+
+ std::list<::Demo::ChatCallbackPrx> _members;
+};
+typedef IceUtil::Handle<ChatRoomMembers> ChatRoomMembersPtr;
+
+class ChatSessionI : public ::Demo::ChatSession, public IceUtil::Mutex
+{
+public:
+
+ ChatSessionI(const ChatRoomMembersPtr&, const std::string&);
+
+ virtual void setCallback(const ::Demo::ChatCallbackPrx&, const Ice::Current&);
+ virtual void say(const std::string&, const Ice::Current&);
+ virtual void destroy(const Ice::Current&);
+
+private:
+
+ ChatRoomMembersPtr _members;
+ ::std::string _userId;
+ ::Demo::ChatCallbackPrx _callback;
+ bool _destroy;
+};
+
+#endif
diff --git a/cpp/demo/Glacier2/chat/Client.cpp b/cpp/demo/Glacier2/chat/Client.cpp
new file mode 100755
index 00000000000..f5fadda8b9d
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/Client.cpp
@@ -0,0 +1,159 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Application.h>
+#include <Glacier2/Router.h>
+#include <Chat.h>
+
+using namespace std;
+using namespace Ice;
+using namespace Demo;
+
+class ChatCallbackI : public ChatCallback
+{
+public:
+
+ virtual void
+ message(const string& data, const Ice::Current&)
+ {
+ cout << data << endl;
+ }
+};
+
+class CallbackClient : public Application
+{
+public:
+
+ virtual int
+ run(int argc, char* argv[])
+ {
+ RouterPrx defaultRouter = communicator()->getDefaultRouter();
+ if(!defaultRouter)
+ {
+ cerr << argv[0] << ": no default router set" << endl;
+ return EXIT_FAILURE;
+ }
+
+ Glacier2::RouterPrx router = Glacier2::RouterPrx::checkedCast(defaultRouter);
+ {
+ if(!router)
+ {
+ cerr << argv[0] << ": configured router is not a Glacier2 router" << endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ ChatSessionPrx session;
+ while(true)
+ {
+ cout << "This demo accepts any user-id / password combination.\n";
+
+ string id;
+ cout << "user id: " << flush;
+ std::getline(cin, id);
+ id = trim(id);
+
+ string pw;
+ cout << "password: " << flush;
+ std::getline(cin, pw);
+ pw = trim(pw);
+
+ try
+ {
+ session = ChatSessionPrx::uncheckedCast(router->createSession(id, pw));
+ break;
+ }
+ catch(const Glacier2::PermissionDeniedException& ex)
+ {
+ cout << "permission denied:\n" << ex.reason << endl;
+ }
+ }
+
+ string category = router->getServerProxy()->ice_getIdentity().category;
+ Identity callbackReceiverIdent;
+ callbackReceiverIdent.name = "callbackReceiver";
+ callbackReceiverIdent.category = category;
+
+ ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Chat.Client");
+ ChatCallbackPrx callback = ChatCallbackPrx::uncheckedCast(
+ adapter->add(new ChatCallbackI, callbackReceiverIdent));
+ adapter->activate();
+
+ session->setCallback(callback);
+
+ menu();
+ do
+ {
+ try
+ {
+ string s;
+ cout << "==> ";
+ std::getline(cin, s);
+ s = trim(s);
+ if(s.empty())
+ {
+ continue;
+ }
+ if(s[0] == '/')
+ {
+ if(s == "/quit")
+ {
+ session->destroy();
+ break;
+ }
+ else
+ {
+ menu();
+ }
+ }
+ else
+ {
+ session->say(s);
+ }
+ }
+ catch(const Exception& ex)
+ {
+ cerr << ex << endl;
+ return EXIT_FAILURE;
+ }
+ }
+ while(cin.good());
+
+ return EXIT_SUCCESS;
+ }
+
+private:
+
+ void
+ menu()
+ {
+ cout << "enter /quit to exit." << endl;
+ }
+
+ string
+ trim(const string& s)
+ {
+ static const string delims = "\t\r\n ";
+ string::size_type last = s.find_last_not_of(delims);
+ if(last != string::npos)
+ {
+ return s.substr(s.find_first_not_of(delims), last+1);
+ }
+ return s;
+ }
+};
+
+int
+main(int argc, char* argv[])
+{
+ CallbackClient app;
+ return app.main(argc, argv, "config");
+}
+
+
diff --git a/cpp/demo/Glacier2/chat/README b/cpp/demo/Glacier2/chat/README
new file mode 100644
index 00000000000..0e65e5bdb07
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/README
@@ -0,0 +1,16 @@
+This example demonstrates the use of a Glacier2 session to create a
+very simple chat server.
+
+To run the demo:
+
+Start the chat server:
+
+$ ./server
+
+In a separate window, start the Glacier2 router:
+
+$ ../../../bin/glacier2router --Ice.Config=config.glacier2
+
+In a separate window, start the client:
+
+$ ./client
diff --git a/cpp/demo/Glacier2/chat/Server.cpp b/cpp/demo/Glacier2/chat/Server.cpp
new file mode 100755
index 00000000000..6a15f47b67d
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/Server.cpp
@@ -0,0 +1,73 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Application.h>
+#include <Glacier2/PermissionsVerifier.h>
+
+#include <ChatSessionI.h>
+
+using namespace std;
+using namespace Ice;
+using namespace Demo;
+
+class DummyPermissionsVerifierI : public Glacier2::PermissionsVerifier
+{
+public:
+
+ virtual bool
+ checkPermissions(const string& userId, const string& passwd, string&, const Ice::Current&) const
+ {
+ return true;
+ }
+};
+
+class ChatRoomSessionManagerI : public Glacier2::SessionManager
+{
+public:
+
+ ChatRoomSessionManagerI() :
+ _members(new ChatRoomMembers())
+ {
+ }
+
+ virtual Glacier2::SessionPrx
+ create(const string& userId, const ::Ice::Current& current)
+ {
+ return Glacier2::SessionPrx::uncheckedCast(current.adapter->addWithUUID(new ChatSessionI(_members, userId)));
+ }
+
+private:
+
+ ChatRoomMembersPtr _members;
+};
+
+class ChatSessionServer : public Application
+{
+public:
+
+ virtual int
+ run(int, char*[])
+ {
+ Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("ChatServer");
+
+ adapter->add(new DummyPermissionsVerifierI, Ice::stringToIdentity("verifier"));
+ adapter->add(new ChatRoomSessionManagerI, Ice::stringToIdentity("ChatRoomSessionManager"));
+ adapter->activate();
+ communicator()->waitForShutdown();
+
+ return EXIT_SUCCESS;
+ }
+};
+
+int
+main(int argc, char* argv[])
+{
+ ChatSessionServer app;
+ return app.main(argc, argv, "config.server");
+}
diff --git a/cpp/demo/Glacier2/chat/chatC.dsp b/cpp/demo/Glacier2/chat/chatC.dsp
new file mode 100755
index 00000000000..3713f233864
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/chatC.dsp
@@ -0,0 +1,153 @@
+# Microsoft Developer Studio Project File - Name="chatC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=chatC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "chatC.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "chatC.mak" CFG="chatC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "chatC - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "chatC - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "chatC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../../include" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Ice.lib IceUtil.lib /nologo /subsystem:console /machine:I386 /out:"client.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+
+!ELSEIF "$(CFG)" == "chatC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../../include" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 Iced.lib IceUtild.lib /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ENDIF
+
+# Begin Target
+
+# Name "chatC - Win32 Release"
+# Name "chatC - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Chat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Client.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Chat.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\Chat.ice
+
+!IF "$(CFG)" == "chatC - Win32 Release"
+
+USERDEP__CHAT_="..\..\..\bin\slice2cpp.exe" "..\..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Chat.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I../../../slice Chat.ice
+
+"Chat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Chat.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "chatC - Win32 Debug"
+
+USERDEP__CHAT_="..\..\..\bin\slice2cpp.exe" "..\..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Chat.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I../../../slice Chat.ice
+
+"Chat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Chat.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/demo/Glacier2/chat/chatS.dsp b/cpp/demo/Glacier2/chat/chatS.dsp
new file mode 100755
index 00000000000..417123a0b2d
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/chatS.dsp
@@ -0,0 +1,161 @@
+# Microsoft Developer Studio Project File - Name="chatS" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=chatS - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "chatS.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "chatS.mak" CFG="chatS - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "chatS - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "chatS - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "chatS - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../../include" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Ice.lib IceUtil.lib /nologo /subsystem:console /machine:I386 /out:"server.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+
+!ELSEIF "$(CFG)" == "chatS - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../../include" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 Iced.lib IceUtild.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ENDIF
+
+# Begin Target
+
+# Name "chatS - Win32 Release"
+# Name "chatS - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Chat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChatSessionI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Server.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Chat.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChatSessionI.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\Chat.ice
+
+!IF "$(CFG)" == "chatS - Win32 Release"
+
+USERDEP__CHAT_="..\..\..\bin\slice2cpp.exe" "..\..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Chat.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I../../../slice Chat.ice
+
+"Chat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Chat.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "chatS - Win32 Debug"
+
+USERDEP__CHAT_="..\..\..\bin\slice2cpp.exe" "..\..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Chat.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I../../../slice Chat.ice
+
+"Chat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Chat.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/demo/Glacier2/chat/config b/cpp/demo/Glacier2/chat/config
new file mode 100644
index 00000000000..3c25364fc24
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/config
@@ -0,0 +1,54 @@
+#
+# The proxy to the Glacier2 router for all outgoing connections. This
+# must match the value of Glacier2.Client.Endpoints in config.glacier2.
+#
+Ice.Default.Router=Glacier2/router:ssl -p 10005
+
+#
+# The proxy for the Glacier2 router, installed in the client's
+# object adapter named Chat.Client. This router proxy must
+# match the value of Glacier2.Client.Endpoints.
+#
+Chat.Client.Router=Glacier2/router:ssl -p 10005
+
+#
+# We don't need any endpoints for the client if we use a
+# router. Incoming requests are received through connections
+# established from the client to the router.
+#
+Chat.Client.Endpoints=
+
+#
+# No active connection management is permitted with Glacier2.
+# Connections must remain established.
+#
+Ice.ConnectionIdleTime=0
+
+#
+# Ice.MonitorConnections defaults to Ice.ConnectionIdleTime, which we
+# set to 0 above. However we still want the connection monitor thread
+# for AMI timeouts (for completeness, even if this demo doesn't use
+# AMI).
+#
+Ice.MonitorConnections=60
+
+#
+# Connection retry is not possible with Glacier2. Connections must
+# remain established.
+#
+Ice.RetryIntervals=-1
+
+#
+# Other settings.
+#
+
+#Ice.Trace.Network=1
+#Ice.Trace.Protocol=1
+Ice.Warn.Connections=1
+
+Ice.Plugin.IceSSL=IceSSL:create
+IceSSL.Client.CertPath=../../../certs
+IceSSL.Client.Config=sslconfig.xml
+IceSSL.Server.CertPath=../../../certs
+IceSSL.Server.Config=sslconfig.xml
+#IceSSL.Trace.Security=1
diff --git a/cpp/demo/Glacier2/chat/config.glacier2 b/cpp/demo/Glacier2/chat/config.glacier2
new file mode 100644
index 00000000000..ffc3e8642b4
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/config.glacier2
@@ -0,0 +1,116 @@
+#
+# We must set the stack size of new threads created by Glacier2. The
+# default on Linux is typically in the 10MB range, which is way too
+# high.
+#
+# Since Glacier2 always uses thread-per-connection mode, we must use
+# the property below to set the thread stack size. Internal Glacier2
+# threads also use this property value.
+#
+Ice.ThreadPerConnection.StackSize=262144
+
+#
+# The client-visible endpoint of Glacier2. This should be an endpoint
+# visible from the public Internet, and it should be secure.
+#
+Glacier2.Client.Endpoints=ssl -p 10005
+
+#
+# The server-visible endpoint of Glacier2. This endpoint is only
+# required if callbacks are needed (leave empty otherwise). This
+# should be an endpoint on an internal network (like 192.168.x.x), or
+# on the loopback, so that the server is not directly accessible from
+# the Internet.
+#
+Glacier2.Server.Endpoints=tcp -h 127.0.0.1
+
+#
+# The configures the session manager. If no external session manager
+# is used, sessions are only handled Glacier2 internally.
+#
+Glacier2.SessionManager=ChatRoomSessionManager:tcp -h 127.0.0.1 -p 10001
+
+#
+# For this demo, we use a dummy permissions verifier that is
+# collocated with the session server process. This dummy permissions
+# verifier allows any user-id / password combination.
+#
+Glacier2.PermissionsVerifier=verifier:tcp -h 127.0.0.1 -p 10001
+
+#
+# The timeout for inactive sessions. If any client session is inactive
+# for longer than this value, the session expires and is removed. The
+# unit is seconds.
+#
+Glacier2.SessionTimeout=30
+
+#
+# Glacier can forward requests buffered or unbuffered. Unbuffered
+# means a lower resource consumption, as buffering requires one
+# additional thread per connected client or server. However, without
+# buffering, messages cannot be batched and message overriding doesn't
+# work either. Also, with unbuffered request forwarding, the caller
+# thread blocks for twoway requests.
+#
+Glacier2.Client.Buffered=1
+Glacier2.Server.Buffered=1
+
+#
+# These two lines instruct Glacier2 to forward contexts both for
+# regular routing, as well as for callbacks (reverse routing).
+#
+Glacier2.Client.ForwardContext=1
+Glacier2.Server.ForwardContext=1
+
+#
+# To prevent Glacier2 from being flooded with requests from or to one
+# particular client, Glacier2 can be configured to sleep for a certain
+# period after all current requests for this client have been
+# forwarded. During this sleep period, new requests for the client are
+# queued. These requests are then all sent once the sleep period is
+# over. The unit is milliseconds.
+#
+Glacier2.Client.SleepTime=500
+Glacier2.Server.SleepTime=500
+
+#
+# With the two settings below, Glacier2 can be instructed to always
+# batch oneways, even if they are sent with a _fwd/o instead of a
+# _fwd/O context.
+#
+Glacier2.Client.AlwaysBatch=0
+Glacier2.Server.AlwaysBatch=0
+
+#
+# Glacier2 always disables active connection management so there is no
+# need to configure this manually. Connection retry does not need to
+# be disabled, as it's safe for Glacier2 to retry outgoing connections
+# to servers. Retry for incoming connections from clients must be
+# disabled in the clients.
+#
+
+#
+# Various settings to trace requests, overrides, etc.
+#
+Glacier2.Client.Trace.Request=1
+Glacier2.Server.Trace.Request=1
+Glacier2.Client.Trace.Override=1
+Glacier2.Server.Trace.Override=1
+Glacier2.Client.Trace.Reject=1
+Glacier2.Trace.Session=1
+Glacier2.Trace.RoutingTable=1
+
+#
+# Other settings.
+#
+
+#Ice.Trace.Network=1
+#Ice.Trace.Protocol=1
+Ice.Warn.Connections=1
+
+Ice.Plugin.IceSSL=IceSSL:create
+IceSSL.Client.CertPath=../../../certs
+IceSSL.Client.Config=sslconfig.xml
+IceSSL.Server.CertPath=../../../certs
+IceSSL.Server.Config=sslconfig.xml
+#IceSSL.Trace.Security=1
diff --git a/cpp/demo/Glacier2/chat/config.server b/cpp/demo/Glacier2/chat/config.server
new file mode 100644
index 00000000000..dd9258a7eb8
--- /dev/null
+++ b/cpp/demo/Glacier2/chat/config.server
@@ -0,0 +1,15 @@
+#
+# The endpoint of the session server's object adapter. This should be
+# an endpoint on an internal network (like 192.168.x.x), or on the
+# loopback, so that the session server is not directly accessible from
+# the Internet.
+#
+ChatServer.Endpoints=tcp -h 127.0.0.1 -p 10001
+
+#
+# Other settings.
+#
+
+#Ice.Trace.Network=1
+#Ice.Trace.Protocol=1
+Ice.Warn.Connections=1