summaryrefslogtreecommitdiff
path: root/js/demo/ChatDemo
diff options
context:
space:
mode:
Diffstat (limited to 'js/demo/ChatDemo')
-rw-r--r--js/demo/ChatDemo/.gitignore4
-rw-r--r--js/demo/ChatDemo/Chat.ice42
-rw-r--r--js/demo/ChatDemo/ChatSession.ice125
-rw-r--r--js/demo/ChatDemo/Client.js601
-rw-r--r--js/demo/ChatDemo/Makefile32
-rw-r--r--js/demo/ChatDemo/Makefile.mak42
-rw-r--r--js/demo/ChatDemo/build.js10
-rw-r--r--js/demo/ChatDemo/index.html271
8 files changed, 1127 insertions, 0 deletions
diff --git a/js/demo/ChatDemo/.gitignore b/js/demo/ChatDemo/.gitignore
new file mode 100644
index 00000000000..c09a9ad9584
--- /dev/null
+++ b/js/demo/ChatDemo/.gitignore
@@ -0,0 +1,4 @@
+Chat.js
+ChatSession.js
+Client.min.js
+Client.min.js.gz
diff --git a/js/demo/ChatDemo/Chat.ice b/js/demo/ChatDemo/Chat.ice
new file mode 100644
index 00000000000..944e903e791
--- /dev/null
+++ b/js/demo/ChatDemo/Chat.ice
@@ -0,0 +1,42 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Chat Demo is licensed to you under the terms described
+// in the CHAT_DEMO_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CHAT_ICE
+#define CHAT_ICE
+
+
+/**
+ *
+ * The Chat module defines types shared by definitions from
+ * ChatSession.ice and PollingChat.ice.
+ *
+ **/
+module Chat
+{
+
+/**
+ *
+ * The InvalidMessageException is raised when a user sends an invalid
+ * message to the server. A message is considered invalid if the
+ * message size exceeds the maximum message size.
+ *
+ **/
+exception InvalidMessageException
+{
+ /**
+ *
+ * The reason why the message was rejected by the server.
+ *
+ **/
+ string reason;
+};
+
+};
+
+#endif
diff --git a/js/demo/ChatDemo/ChatSession.ice b/js/demo/ChatDemo/ChatSession.ice
new file mode 100644
index 00000000000..e10958338ba
--- /dev/null
+++ b/js/demo/ChatDemo/ChatSession.ice
@@ -0,0 +1,125 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Chat Demo is licensed to you under the terms described
+// in the CHAT_DEMO_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CHAT_SESSION_ICE
+#define CHAT_SESSION_ICE
+
+#include <Ice/BuiltinSequences.ice>
+#include <Glacier2/Session.ice>
+#include <Chat.ice>
+
+module Chat
+{
+
+/**
+ *
+ * The ChatRoomCallback interface is the interface that clients implement
+ * as their callback object.
+ *
+ * The server calls operations of this interface to communicate
+ * with connected clients.
+ *
+ **/
+interface ChatRoomCallback
+{
+ /**
+ *
+ * The server invokes this operation when the client sets the callback
+ * for a session. This provides the client with the initial list of users
+ * currently in the chat room.
+ *
+ * @param users The names of users currently in the chat room.
+ *
+ **/
+ void init(Ice::StringSeq users);
+
+ /**
+ *
+ * The server invokes this operation to deliver a message
+ * that was sent to the chat room.
+ *
+ * @param name The name of the user that send the message.
+ *
+ * @param message The contents of the message.
+ *
+ * @param timestamp The time at which the message was sent.
+ *
+ **/
+ void send(long timestamp, string name, string message);
+
+ /**
+ *
+ * The server invokes this operation when a user joins
+ * the chat room.
+ *
+ * @param name The name of the user that joined the chat room.
+ *
+ * @param timestamp The time at which the user joined the chat room.
+ *
+ **/
+ void join(long timestamp, string name);
+
+ /**
+ *
+ * The servers invokes this operation when a user leaves
+ * the chat room.
+ *
+ * @param name The name of the user that left the chat room.
+ *
+ * @param timestamp The time at which the user left the chat room.
+ *
+ **/
+ void leave(long timestamp, string name);
+};
+
+/**
+ *
+ * A ChatSession is a custom Glacier2::Session for clients that use
+ * Glacier2 and support callbacks (C++, Java, and .NET clients).
+ *
+ * @see Glacier2::Session
+ *
+ **/
+interface ChatSession extends Glacier2::Session
+{
+ /**
+ *
+ * The setCallback operation is called by clients to set the
+ * callback used to receive notification of activity in the
+ * room. Clients receive notifications as soon as they call this
+ * operation (before setCallback returns).
+ *
+ * The first callback made by the server is a call to
+ * ChatRoomCallback::init, which delivers the current list of
+ * users to the client.
+ *
+ * @param cb The callback the server uses to deliver notifications.
+ *
+ * @see ChatRoomCallback
+ *
+ **/
+ void setCallback(ChatRoomCallback* cb);
+
+ /**
+ *
+ * Send a message to the chat room.
+ *
+ * @param message The message to be sent.
+ *
+ * @return The time at which the message is sent.
+ *
+ * @throws InvalidMessageException should the message be invalid.
+ *
+ **/
+ long send(string message) throws InvalidMessageException;
+};
+
+};
+
+#endif
diff --git a/js/demo/ChatDemo/Client.js b/js/demo/ChatDemo/Client.js
new file mode 100644
index 00000000000..3912cfdcecf
--- /dev/null
+++ b/js/demo/ChatDemo/Client.js
@@ -0,0 +1,601 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 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.
+//
+// **********************************************************************
+
+(function(){
+
+var Promise = Ice.Promise;
+var RouterPrx = Glacier2.RouterPrx;
+var ChatRoomCallbackPrx = Chat.ChatRoomCallbackPrx;
+var ChatSessionPrx = Chat.ChatSessionPrx;
+
+//
+// Chat client state
+//
+var State = {Disconnected: 0, Connecting: 1, Connected: 2};
+var maxMessageSize = 1024;
+var communicator;
+var username;
+var state;
+var hasError = false;
+
+var hostname = document.location.hostname || "127.0.0.1";
+
+//
+// Servant that implements the ChatCallback interface.
+// The message operation just writes the received data
+// to the output textarea.
+//
+var ChatCallbackI = Ice.Class(Chat.ChatRoomCallback, {
+ init: function(users)
+ {
+ users.forEach(
+ function(name)
+ {
+ userJoined(name);
+ });
+ },
+ send: function(timestamp, name, message)
+ {
+ if(name != username)
+ {
+ writeLine(formatDate(timestamp.toNumber()) + " - <" + name + "> - " + unescapeHtml(message));
+ }
+ },
+ join: function(timestamp, name)
+ {
+ writeLine(formatDate(timestamp.toNumber()) + " - <system-message> - " + name + " joined.");
+ userJoined(name);
+ },
+ leave: function(timestamp, name)
+ {
+ writeLine(formatDate(timestamp.toNumber()) + " - <system-message> - " + name + " left.");
+ userLeft(name);
+ }
+});
+
+function userJoined(name)
+{
+ if(name == username)
+ {
+ $("#users").append("<li id=\"" + name + "\"><b>" + name + "</b></li>");
+ }
+ else
+ {
+ $("#users").append("<li id=\"" + name + "\"><a href=\"#\">" + name + "</a></li>");
+ $("#users #" + name).click(
+ function()
+ {
+ var s = $("#input").val();
+ if(s.length > 0)
+ {
+ s += " ";
+ }
+ s += "@" + name + " ";
+ $("#input").val(s);
+ $("#input").focus();
+ return false;
+ });
+ }
+ $("#users").append("<li class=\"divider\"></li>");
+}
+
+function userLeft(name)
+{
+ $("#users #" + name).off("click");
+ $("#users #" + name).next().remove();
+ $("#users #" + name).remove();
+}
+
+var signin = function()
+{
+ assert(state === State.Disconnected);
+ setState(State.Connecting).then(
+ function()
+ {
+ //
+ // Initialize the communicator with the Ice.Default.Router property
+ // set to the chat demo Glacier2 router.
+ //
+ var id = new Ice.InitializationData();
+ id.properties = Ice.createProperties();
+ id.properties.setProperty("Ice.Default.Router",
+ "Glacier2/router:wss -p 9090 -h " + hostname + " -r /chatwss");
+ communicator = Ice.initialize(id);
+
+ //
+ // Get a proxy to the Glacier2 router using checkedCast to ensure
+ // the Glacier2 server is available.
+ //
+ return RouterPrx.checkedCast(communicator.getDefaultRouter()).then(
+ function(router)
+ {
+ //
+ // Create a session with the Glacier2 router.
+ //
+ return router.createSession(
+ $("#username").val(), $("#password").val()).then(
+ function(session)
+ {
+ run(router, ChatSessionPrx.uncheckedCast(session));
+ });
+ });
+ }
+ ).exception(
+ function(ex)
+ {
+ //
+ // Handle any exceptions that occurred during session creation.
+ //
+ if(ex instanceof Glacier2.PermissionDeniedException)
+ {
+ setState(State.Disconnected, "permission denied:\n" + ex.reason);
+ }
+ else if(ex instanceof Glacier2.CannotCreateSessionException)
+ {
+ setState(State.Disconnected, "cannot create session:\n" + ex.reason);
+ }
+ else if(ex instanceof Ice.ConnectFailedException)
+ {
+ setState(State.Disconnected, "connection to server failed");
+ }
+ else
+ {
+ setState(State.Disconnected, ex.toString());
+ }
+ });
+};
+
+var run = function(router, session)
+{
+ assert(state === State.Connecting);
+ //
+ // The chat promise is used to wait for the completion of chatting
+ // state. The completion could happen because the user signed out,
+ // or because there is an exception.
+ //
+ var chat = new Promise();
+ //
+ // Get the session timeout and the router client category, then
+ // create the client object adapter.
+ //
+ // Use Ice.Promise.all to wait for the completion of all the
+ // calls.
+ //
+ Promise.all(
+ router.getSessionTimeout(),
+ router.getCategoryForClient(),
+ communicator.createObjectAdapterWithRouter("", router)
+ ).then(
+ function()
+ {
+ //
+ // The results of each promise are provided in an array.
+ //
+ var timeout = arguments[0][0];
+ var category = arguments[1][0];
+ var adapter = arguments[2][0];
+
+ //
+ // Call refreshSession in a loop to keep the
+ // session alive.
+ //
+ var refreshSession = function()
+ {
+ router.refreshSession().exception(
+ function(ex)
+ {
+ chat.fail(ex);
+ }
+ ).delay(timeout.toNumber() * 500).then(
+ function()
+ {
+ if(!chat.completed())
+ {
+ refreshSession();
+ }
+ });
+ };
+ refreshSession();
+
+ //
+ // Create the ChatCallback servant and add it to the
+ // ObjectAdapter.
+ //
+ var callback = ChatRoomCallbackPrx.uncheckedCast(
+ adapter.add(new ChatCallbackI(),
+ new Ice.Identity("callback", category)));
+
+ //
+ // Set the chat session callback.
+ //
+ return session.setCallback(callback);
+ }
+ ).then(
+ function()
+ {
+ return setState(State.Connected);
+ }
+ ).then(
+ function()
+ {
+ //
+ // Process input events in the input textbox until
+ // the chat promise is completed.
+ //
+ $("#input").keypress(
+ function(e)
+ {
+ if(!chat.completed())
+ {
+ //
+ // When enter key is pressed, we send a new message
+ // using the session's say operation and then reset
+ // the textbox contents.
+ //
+ if(e.which === 13)
+ {
+ var msg = $(this).val();
+ if(msg.length > 0)
+ {
+ $(this).val("");
+ if(msg.length > maxMessageSize)
+ {
+ writeLine("<system-message> - Message length exceeded, " +
+ "maximum length is " + maxMessageSize + " characters.");
+ }
+ else
+ {
+ session.send(msg).then(
+ function(timestamp)
+ {
+ writeLine(formatDate(timestamp.toNumber()) + " - <" +
+ username + "> - " + msg);
+ },
+ function(ex)
+ {
+ if(ex instanceof Chat.InvalidMessageException)
+ {
+ writeLine("<system-message> - " + ex.reason);
+ }
+ else
+ {
+ chat.fail(ex);
+ }
+ });
+ }
+ }
+ return false;
+ }
+ }
+ });
+
+ //
+ // Exit the chat loop accepting the chat promise.
+ //
+ $("#signout").click(
+ function(){
+ chat.succeed();
+ return false;
+ });
+
+ return chat;
+ }
+ ).finally(
+ function()
+ {
+ //
+ // Reset the input text box and chat output textarea.
+ //
+ $("#input").val("");
+ $("#input").off("keypress");
+ $("#signout").off("click");
+ $("#output").val("");
+
+ //
+ // Destroy the session.
+ //
+ return router.destroySession();
+ }
+ ).then(
+ function()
+ {
+ setState(State.Disconnected);
+ }
+ ).exception(
+ function(ex)
+ {
+ //
+ // Handle any exceptions that occurred while running.
+ //
+ setState(State.Disconnected, ex.toString());
+ });
+};
+
+//
+// Do a transition from "from" screen to "to" screen. Return
+// a promise that allows us to wait for the transition to
+// complete. If to screen is undefined just animate out the
+// from screen.
+//
+var transition = function(from, to)
+{
+ var p = new Ice.Promise();
+
+ $(from).animo({ animation: "flipOutX", keep: true },
+ function()
+ {
+ $(from).css("display", "none");
+ if(to)
+ {
+ $(to).css("display", "block")
+ .animo({ animation: "flipInX", keep: true },
+ function(){ p.succeed(); });
+ }
+ else
+ {
+ p.succeed();
+ }
+ });
+ return p;
+};
+
+//
+// Set default height of output textarea
+//
+$("#output").height(300);
+
+//
+// Animate the loading progress bar.
+//
+var w = 0;
+var progress;
+
+var startProgress = function()
+{
+ if(!progress)
+ {
+ progress = setInterval(
+ function()
+ {
+ w = w >= 100 ? 0 : w + 1;
+ $("#loading .meter").css("width", w.toString() + "%");
+ },
+ 20);
+ }
+};
+
+var stopProgress = function(completed)
+{
+ if(progress)
+ {
+ clearInterval(progress);
+ progress = null;
+ if(completed)
+ {
+ $("#loading .meter").css("width", "100%");
+ }
+ }
+};
+
+//
+// Dismiss error message on click.
+//
+function dismissError()
+{
+ transition("#signin-alert");
+ hasError = false;
+ return false;
+}
+
+//
+// Switch the state and return a promise that is fulfilled
+// when state change completes.
+//
+function setState(newState, error)
+{
+ assert(state !== newState);
+ switch(newState)
+ {
+ case State.Disconnected:
+ {
+ assert(state === undefined ||
+ state === State.Connecting ||
+ state === State.Connected);
+
+ $("#users a").off("click");
+ $("#users").html("");
+ $(window).off("beforeunload");
+
+ //
+ // First destroy the communicator if needed then do
+ // the screen transition.
+ //
+ return Promise.try(
+ function()
+ {
+ if(communicator)
+ {
+ var c = communicator;
+ communicator = null;
+ return c.destroy();
+ }
+ }
+ ).finally(
+ function()
+ {
+ if(state !== undefined)
+ {
+ if(error)
+ {
+ hasError = true;
+ stopProgress(false);
+ $("#signin-alert span").text(error);
+ return transition("#loading", "#signin-alert").then(
+ function(){
+ $("#loading .meter").css("width", "0%");
+ $("#signin-form").css("display", "block")
+ .animo({ animation: "flipInX", keep: true });
+ });
+ }
+ else
+ {
+ return transition("#chat-form", "#signin-form");
+ }
+ }
+ }
+ ).then(
+ function()
+ {
+ $("#username").focus();
+ $("#username").keypress(
+ function(e)
+ {
+ //
+ // After enter key is pressed in the username input,
+ // switch focus to password input.
+ //
+ if(e.which === 13)
+ {
+ $("#password").focus();
+ return false;
+ }
+ });
+
+ $("#password").keypress(
+ function(e)
+ {
+ //
+ // After enter key is pressed in the password input,
+ // sign-in.
+ //
+ if(e.which === 13)
+ {
+ signin();
+ return false;
+ }
+ });
+
+ $("#signin").click(function(){
+ signin();
+ return false;
+ });
+
+ state = State.Disconnected;
+ });
+ }
+ case State.Connecting:
+ {
+ assert(state === State.Disconnected);
+ username = formatUsername($("#username").val());
+
+ //
+ // Remove the signin form event handlers.
+ //
+ $("#username").off("keypress");
+ $("#password").off("keypress");
+ $("#signin").off("click");
+
+ //
+ // Dismiss any previous error message.
+ //
+ if(hasError)
+ {
+ dismissError();
+ }
+
+ //
+ // Setup a before unload handler to prevent accidentally navigating
+ // away from the page while the user is connected to the chat server.
+ //
+ $(window).on("beforeunload",
+ function()
+ {
+ return "If you navigate away from this page, the current chat session will be lost.";
+ });
+
+ //
+ // Transition to loading screen
+ //
+ return transition("#signin-form", "#loading").then(
+ function()
+ {
+ startProgress();
+ state = State.Connecting;
+ });
+ }
+ case State.Connected:
+ {
+ //
+ // Stop animating the loading progress bar and
+ // transition to the chat screen.
+ //
+ assert(state === State.Connecting);
+ stopProgress(true);
+ return transition("#loading", "#chat-form").then(
+ function()
+ {
+ $("#loading .meter").css("width", "0%");
+ $("#input").focus();
+ state = State.Connected;
+ });
+ }
+ }
+}
+//
+// Switch to initial state.
+//
+setState(State.Disconnected);
+
+function formatDate(timestamp)
+{
+ var d = new Date();
+ d.setTime(timestamp);
+ return d.toLocaleTimeString().trim();
+}
+
+function formatUsername(s)
+{
+ return s.length < 2 ?
+ s.toUpperCase() :
+ s.substring(0, 1).toUpperCase() + s.substring(1, s.length).toLowerCase();
+}
+
+function writeLine(s)
+{
+ $("#output").val($("#output").val() + s + "\n");
+ $("#output").scrollTop($("#output").get(0).scrollHeight);
+}
+
+var entities = [
+ {entity: /&quot;/g, value: "\""},
+ {entity: /&#39;/g, value: "'"},
+ {entity: /&lt;/g, value: "<"},
+ {entity: /&gt;/g, value: ">"},
+ {entity: /&amp;/g, value: "&"}];
+
+function unescapeHtml(msg)
+{
+ var e;
+ for(var i = 0; i < entities.length; ++i)
+ {
+ e = entities[i];
+ msg = msg.replace(e.entity, e.value);
+ }
+ return msg;
+}
+
+function assert(v)
+{
+ if(!v)
+ {
+ throw new Error("Assertion failed");
+ }
+}
+
+}());
diff --git a/js/demo/ChatDemo/Makefile b/js/demo/ChatDemo/Makefile
new file mode 100644
index 00000000000..fd88dd8cf0e
--- /dev/null
+++ b/js/demo/ChatDemo/Makefile
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 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.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+TARGETS = Chat.js ChatSession.js
+
+ifeq ($(OPTIMIZE),yes)
+TARGETS := $(TARGETS) Client.min.js Client.min.js.gz
+endif
+
+include $(top_srcdir)/config/Make.rules.js
+
+SLICE2JSFLAGS := $(SLICE2JSFLAGS) -I$(slicedir) -I.
+
+
+ifeq ($(OPTIMIZE),yes)
+
+CLOSUREFLAGS := $(CLOSUREFLAGS) --warning_level QUIET
+
+Client.min.js Client.min.js.gz: $(libdir)/Ice.min.js $(libdir)/Glacier2.min.js Client.js Chat.js ChatSession.js
+ @rm -f browser/Client.min.js browser/Client.min.js.gz
+ java -jar $(CLOSURE_PATH)/compiler.jar $(CLOSUREFLAGS) --js $(libdir)/Ice.min.js $(libdir)/Glacier2.min.js \
+ Chat.js ChatSession.js Client.js --js_output_file Client.min.js
+ gzip -c9 Client.min.js > Client.min.js.gz
+endif
diff --git a/js/demo/ChatDemo/Makefile.mak b/js/demo/ChatDemo/Makefile.mak
new file mode 100644
index 00000000000..b5533e67469
--- /dev/null
+++ b/js/demo/ChatDemo/Makefile.mak
@@ -0,0 +1,42 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+TARGETS = Chat.js ChatSession.js
+
+!if "$(OPTIMIZE)" == "yes"
+TARGETS = $(TARGETS) Client.min.js
+
+!if "$(GZIP_PATH)" != ""
+TARGETS = $(TARGETS) Client.min.js.gz
+!endif
+
+!endif
+
+!include $(top_srcdir)\config\Make.rules.mak.js
+
+SLICE2JSFLAGS = $(SLICE2JSFLAGS) -I"$(slicedir)" -I.
+
+!if "$(OPTIMIZE)" == "yes"
+
+CLOSUREFLAGS = $(CLOSUREFLAGS) --warning_level QUIET
+
+Client.min.js: Client.js Chat.js ChatSession.js $(libdir)\Ice.min.js $(libdir)\Glacier2.min.js
+ @del /q Client.min.js
+ java -jar $(CLOSURE_PATH)\compiler.jar $(CLOSUREFLAGS) --js $(libdir)\Ice.js $(libdir)\Glacier2.js \
+ Chat.js ChatSession.js Client.js --js_output_file Client.min.js
+
+!if "$(GZIP_PATH)" != ""
+Client.min.js.gz: Client.min.js
+ @del /q Client.min.js.gz
+ "$(GZIP_PATH)" -c9 Client.min.js > Client.min.js.gz
+!endif
+
+!endif
diff --git a/js/demo/ChatDemo/build.js b/js/demo/ChatDemo/build.js
new file mode 100644
index 00000000000..b79242b8999
--- /dev/null
+++ b/js/demo/ChatDemo/build.js
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 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.
+//
+// **********************************************************************
+
+require ("../../config/build").build(__dirname, ["Chat.ice", "ChatSession.ice"], ["-I."]);
diff --git a/js/demo/ChatDemo/index.html b/js/demo/ChatDemo/index.html
new file mode 100644
index 00000000000..22a5e1ba836
--- /dev/null
+++ b/js/demo/ChatDemo/index.html
@@ -0,0 +1,271 @@
+<!doctype html>
+<html class="no-js" lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Chat Demo | Ice for JavaScript</title>
+ <!-- Bundle with all the stylesheets used to build the user interface,
+ see assets/Makefile in your distribution for details -->
+ <link rel="stylesheet" type="text/css" href="../../assets/common.css" />
+ <link rel="icon" type="image/x-icon" href="../../assets/favicon.ico">
+ </head>
+ <body>
+ <!-- Header section that contains title and navigation bar -->
+ <section id="header">
+ <nav class="top-bar" data-topbar>
+ <ul class="title-area">
+ <li class="name">
+ <h1><a href="../../index.html">Ice for JavaScript</a></h1>
+ </li>
+ <li class="toggle-topbar menu-icon"><a href="#">Menu</a></li>
+ </ul>
+ <section class="top-bar-section">
+ <!-- Right Nav Section -->
+ <ul class="right">
+ <li class="divider"></li>
+ <li><a href="#" id="viewReadme">Readme</a></li>
+ <li><a href="#" id="viewSource">Source</a></li>
+ </ul>
+ </section>
+ </nav>
+ <ul class="breadcrumbs">
+ <li><a href="../../index.html">Ice</a></li>
+ <li><a href="../index.html">Demos</a></li>
+ <li class="current"><a href="#">Chat Demo</a></li>
+ </ul>
+ </section>
+ <!-- Main section that contains the user interface -->
+ <section role="main" id="body">
+ <!-- Sign In Form -->
+ <div class="row" id="signin-form">
+ <div class="large-12 medium-12 columns">
+ <form>
+ <div class="row">
+ <div class="small-4 medium-3 columns">
+ <label class="right inline" for="username">Username:</label>
+ </div>
+ <div class="small-8 medium-9 columns">
+ <input type="text" id="username"/>
+ </div>
+ </div>
+ <div class="row">
+ <div class="small-4 medium-3 columns">
+ <label class="right inline" for="password">Password:</label>
+ </div>
+ <div class="small-8 medium-9 columns">
+ <input type="password" id="password"/>
+ </div>
+ </div>
+ <div class="row">
+ <div class="small-12 columns">
+ <a href="#" class="button small right" id="signin">Sign in</a>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ <!-- Error Alert -->
+ <div class="row" style="display:none;opacity:0;" id="signin-alert">
+ <div class="large-12 medium-12 columns">
+ <div data-alert class="alert-box warning round">
+ <span class="error-message"></span>
+ </div>
+ </div>
+ </div>
+ <!-- Loading Indicator -->
+ <div class="row" id="loading" style="display:none;opacity:0;">
+ <div class="large-12 medium-12 columns">
+ <div class="panel">
+ <h3>Loading Please Wait...</h3>
+ <div class="progress radius round">
+ <span class="meter" style="width:0%"></span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- Chat Form -->
+ <div class="row" id="chat-form" style="display:none;opacity:0;">
+ <div class="large-12 medium-12 columns">
+ <nav class="top-bar" data-topbar>
+ <ul class="title-area">
+ <li class="name">
+ <h1><a href="#">Chat Demo</a></h1>
+ </li>
+ <li class="toggle-topbar menu-icon"><a href="#">Menu</a></li>
+ </ul>
+ <section class="top-bar-section">
+ <!-- Right Nav Section -->
+ <ul class="right">
+ <li class="divider"></li>
+ <li class="has-form">
+ <a href="#" id="signout" class="button">Sign out</a>
+ </li>
+ </ul>
+ </section>
+ </nav>
+ <form>
+ <div class="row">
+ <div class="large-2 columns">
+ <ul id="users" class="side-nav"></ul>
+ </div>
+ <div class="large-10 columns">
+ <textarea id="output" class="disabled" readonly></textarea>
+ </div>
+ </div>
+ <div class="row">
+ <div class="large-12 columns">
+ <input type="text" id="input" autocomplete="off"/>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </section>
+ <!-- Modal dialog to show the client README -->
+ <div id="readme-modal" class="reveal-modal" data-reveal>
+ <h4>Chat Demo Readme</h4>
+ <hr/>
+ <p>This demo implements a push client for the
+ <a href="http://www.zeroc.com/chat/index.html">ZeroC's Chat Demo Application</a>. You can use the
+ <a href="#" class="chatbutton">Live Client</a> if you don't want to setup your own server.
+ </p>
+
+ <p>To set up the server follow the instructions from the
+ <a href="http://www.zeroc.com/chat/download.html">Chat Demo Distribution</a>.</p>
+
+ <p>You will need to update the Glacier2 configuration to include WSS endpoints.
+ Edit <code>ChatDemo-1.4.0/config/config.glacier2router</code>
+ and update the <code>Glacier2.Client.Endpoints</code> property with the value shown below:</p>
+ <p>
+ <code style="color:#858585;font-weight:normal;font-size:80%;">
+ Glacier2.Client.Endpoints=ssl -p 4064 -t 10000 -h 127.0.0.1:tcp -p 4502 -t 10000 -h 127.0.0.1:wss -p 5064 -t 10000 -h 127.0.0.1
+ </code>
+ </p>
+ <p>You also need to enable the Web Socket transport plug-in. Add the following lines
+ to <code>ChatDemo-1.4.0/config/config.glacier2router</code>:</p>
+ <p>
+ <code style="color:#858585;font-weight:normal;font-size:80%;">
+ Ice.Plugin.IceWS=IceWS:createIceWS
+ </code>
+ </p>
+
+ <p>After making those modifications to the Glacier2 router configuration, you can start the Chat Demo
+ server and Glacier2 router as documented in the Chat Demo distribution.</p>
+
+ <div class="panel callout radius">
+ <p>You must configure your environment to run IceWS applications as documented in the Ice for JavaScript
+ <a href="http://doc.zeroc.com/display/Rel/Ice+for+JavaScript+0.1.0+Release+Notes">Release Notes</a>.</p>
+ </div>
+
+ <p>Once you have configured and started the Chat Demo server and router,
+ you can log into the chat using the sign-in form below.</p>
+
+ <h4>Using the minified scripts</h4>
+ <p>When the demo is built with optimizations enabled, it creates a minified
+ script <code>browser/Client.min.js</code> that includes:
+ </p>
+ <ul>
+ <li>Ice.js (The Ice run-time library)</li>
+ <li>Glacier2.js (The Glacier2 library)</li>
+ <li>Chat.js & ChatSession.js (The generated code for this demo)</li>
+ <li>Client.js (The client application)</li>
+ </ul>
+ <p>To use the minified version you should edit the <code>demo/ChatDemo/index.html</code>
+ file and comment out the non-optimized scripts:</p>
+ <pre>
+ &lt;!-- Scripts used during development, for optimized builds
+ comment the following scripts and uncomment browser/Client.min.js
+ below -->
+ &lt;!-- Ice.js (Ice run-time library) --&gt;
+ &lt;script type="text/javascript" src="../../../lib/Ice.js"&gt;&lt;/script&gt;
+ &lt;!-- Glacier2.js (Glacier2 run-time library) --&gt;
+ &lt;script type="text/javascript" src="../../../lib/Glacier2.js"&gt;&lt;/script&gt;
+ &lt;!-- Chat.js (Demo generated code) --&gt;
+ &lt;script type="text/javascript" src="Chat.js"&gt;&lt;/script&gt;
+ &lt;!-- ChatSession.js (Demo generated code) --&gt;
+ &lt;script type="text/javascript" src="ChatSession.js"&gt;&lt;/script&gt;
+ &lt;!-- Client.js (Chat Demo Application) --&gt;
+ &lt;script type="text/javascript" src="Client.js"&gt;&lt;/script&gt;
+ </pre>
+ <p>Then uncomment the script tag for the minified version</p>
+ <pre>
+ &lt;!-- Uncomment the following script to use a minified version of the
+ scripts that includes: the Ice and Glacier2 run-time libraries,
+ the generated code and the demo application. --&gt;
+ &lt;!--&lt;script src="Client.min.js"&gt;&lt;/script&gt;--&gt;
+ </pre>
+ <a class="close-reveal-modal">&#215;</a>
+ </div>
+ <!-- Modal dialog to show the client source code -->
+ <div id="source-modal" class="reveal-modal" data-reveal>
+ <a class="close-reveal-modal">&#215;</a>
+ <dl class="tabs" data-tab>
+ <dt></dt>
+ <dd class="active"><a href="#panel2-1">Slice</a></dd>
+ <dd><a href="#panel2-2">JavaScript</a></dd>
+ <dd><a href="#panel2-3">HTML</a></dd>
+ </dl>
+ <div class="tabs-content">
+ <div class="content active" id="panel2-1">
+ <h6>File: ChatDemo/Chat.ice</h6>
+ <pre class="source language-c" data-code="Chat.ice"></pre>
+ <h6>File: ChatDemo/ChatSession.ice</h6>
+ <pre class="source language-c" data-code="ChatSession.ice"></pre>
+ </div>
+ <div class="content" id="panel2-2">
+ <h6>File: ChatDemo/Client.js</h6>
+ <pre class="source" data-code="Client.js"></pre>
+ </div>
+ <div class="content" id="panel2-3">
+ <h6>File: ChatDemo/index.html</h6>
+ <pre class="source" data-code="index.html"></pre>
+ </div>
+ </div>
+ </div>
+ <!-- Footer section -->
+ <section id="footer">
+ <div class="logo">
+ <h4><strong>ZeroC</strong></h4>
+ </div>
+ <div class="copyright">
+ <h6>© 2014 ZeroC, Inc. All rights reserved.</h6>
+ </div>
+ </section>
+ <!-- Bundle with all the scripts used to build the user interface,
+ see assets/Makefile in your distribution for details -->
+ <script type="text/javascript" src="../../assets/common.min.js"></script>
+ <!-- Scripts used during development, for optimized builds
+ comment the following scripts and uncomment Client.min.js
+ below -->
+ <!-- Ice.js (Ice run-time library) -->
+ <script type="text/javascript" src="../../lib/Ice.js"></script>
+ <!-- Glacier2.js (Glacier2 run-time library) -->
+ <script type="text/javascript" src="../../lib/Glacier2.js"></script>
+ <!-- Chat.js (Demo generated code) -->
+ <script type="text/javascript" src="Chat.js"></script>
+ <!-- ChatSession.js (Demo generated code) -->
+ <script type="text/javascript" src="ChatSession.js"></script>
+ <!-- Client.js (Chat Demo Application) -->
+ <script type="text/javascript" src="Client.js"></script>
+ <!-- Uncomment the following script to use a minified version of the
+ scripts that includes: the Ice and Glacier2 run-time libraries,
+ the generated code and the demo application. -->
+ <!--<script type="text/javascript" src="Client.min.js"></script>-->
+
+ <script type="text/javascript">
+ $(".chatbutton").click(
+ function(e)
+ {
+ window.open("https://demo.zeroc.com/chat/js/index.html", "ChatDemo",
+ "width=800,height=600,location=no,directories=no,status=yes," +
+ "menubar=no,scrollbars=yes,resizable=yes,toolbar=no");
+ return false;
+ });
+
+ if(["http:", "https:"].indexOf(document.location.protocol) !== -1)
+ {
+ checkGenerated(["Chat.js"]);
+ }
+ </script>
+ </body>
+</html>