Home » Demos » APE real time chat

APE real time chat



About this demo


This is a simple chat demo, showing the real-time reactivity of APE. Here, APE is not used as a middleware, and the built-in message queue system is used to enable the communication between users on channels.

Which features this demo is using?

  • nickname.js
  • Sessions



A simple chat demo, multi-user and private messages.

APE real time chat

A simple chat demo, multi-user and private messages.

Demo of multi-user moving and chating in real time.

Move demo

Demo of multi-user moving and chating in real time.

Live tweets from Twitter trends, in real time!

Live tweets

Live tweets from Twitter trends, in real time!


Gateway to IRC using the TCPSocket feature. Come chat with us ;)

TCPSocket Demo (IRC)

Gateway to IRC using the TCPSocket feature. Come chat with us ;)

A demo of a small massive multiplayer role playing game!

MMORPG

A demo of a small massive multiplayer role playing game!

Draw with everyone in real time!

Pixelbox

Draw with everyone in real time!


Homepage demo

Homepage demo

This is the demo from the home page of APE, but you've probably already seen it ;-)


Study the source code


Check out the Client JavaScript, HTML and ServerSide JavaScript source code of this demo by reading the following :


  1. <script type="text/javascript" src="http://static.weelya.com/weelya_ape/includes/tpl/js/APE_JSF/Demos/Chat/demo.js"></script>
  2. <script type="text/javascript">
  3.         window.addEvent('domready', function() {
  4.                 var chat = new APE.Chat({'container':$('ape_master_container')});
  5.                 chat.load({
  6.                         'identifier': 'chatdemo',
  7.                         'channel': 'test'
  8.                 });
  9.         });
  10. </script>
  11. <link type="text/css" rel="stylesheet"  href="/demos/Chat/demo.css" title="APE Stylesheet" />
  12.  
  1. APE.Chat = new Class({
  2.  
  3.         Implements: [APE.Client, Options],
  4.  
  5.         options:{
  6.                 container: null,
  7.                 logs_limit: 10
  8.         },
  9.  
  10.         initialize: function(core,options){
  11.                 this.core = core;
  12.                 this.setOptions(options);
  13.                 this.options.container = $(this.options.container) || document.body;
  14.                 this.els = {};
  15.                 this.currentPipe = null;
  16.                 this.logging = true;
  17.                 this.addEvent('init', this.createChat);
  18.                 this.addEvent('pipeCreate', this.createPipe);
  19.                 this.addEvent('userJoin', this.createUser);
  20.                 this.addEvent('userLeft', this.deleteUser);
  21.                 this.onCmd('send', this.cmdSend);
  22.                 this.addEvent('restoreEnd',this.restoreEnd);
  23.                 this.onRaw('data', this.rawData);
  24.                 this.onError('004', this.reset);
  25.                 this.addEvent('sessions', function() {
  26.                                 console.log(arguments);
  27.                 });
  28.                 //If name is not set & it's not a session restore ask user for his nickname
  29.                 if(!this.options.name && !this.core.options.restore){
  30.                         this.promptName();
  31.                 }else{
  32.                         this.start();
  33.                 }
  34.         },
  35.  
  36.         promptName: function(error){
  37.                 this.els.namePrompt = {};
  38.                 this.els.namePrompt.div = new Element('form',{'class':'ape_name_prompt','text':'Choose a nickname : '}).inject(this.options.container)
  39.                 this.els.namePrompt.div.addEvent('submit',function(ev){
  40.                         ev.stop();
  41.                         this.options.name = this.els.namePrompt.input.get('value');
  42.                         this.els.namePrompt.div.dispose();
  43.                         this.start()
  44.                 }.bindWithEvent(this));
  45.                 this.els.namePrompt.input = new Element('input',{'class':'text'}).inject(this.els.namePrompt.div);
  46.                 new Element('input',{'class':'submit','type':'submit','value':'GO!'}).inject(this.els.namePrompt.div)
  47.         },
  48.  
  49.         start: function(){
  50.                 this.core.start(this.options.name);
  51.         },
  52.  
  53.         setPipeName: function(pipe, options){
  54.                 if(options.name){
  55.                         pipe.name = options.name;
  56.                         return;
  57.                 }
  58.                 if(options.sender){
  59.                         pipe.name = options.sender.properties.name;
  60.                 }else{
  61.                         pipe.name = options.pipe.properties.name;
  62.                 }
  63.         },
  64.  
  65.         getCurrentPipe: function(){
  66.                 return this.currentPipe;
  67.         },
  68.  
  69.         setCurrentPipe: function(pubid,save){
  70.                 save = !save;
  71.                 if(this.currentPipe){
  72.                         this.currentPipe.els.tab.addClass('unactive');
  73.                         this.currentPipe.els.container.addClass('ape_none');
  74.                 }
  75.                 this.currentPipe = this.core.pipes.get(pubid);
  76.                 this.currentPipe.els.tab.removeClass('new_message');
  77.                 this.currentPipe.els.tab.removeClass('unactive');
  78.                 this.currentPipe.els.container.removeClass('ape_none');
  79.                 this.scrollMsg(this.currentPipe);
  80.                 if(save) this.core.setSession('currentPipe',this.currentPipe.getPubid());
  81.                 return this.currentPipe;
  82.         },
  83.  
  84.         cmdSend: function(pipe, sessid, pubid, message){
  85.                 this.writeMessage(pipe,message,this.core.user);
  86.         },
  87.  
  88.         rawData: function(raw, pipe){
  89.                 this.writeMessage(pipe,raw.datas.msg,raw.datas.sender);
  90.         },
  91.  
  92.         parseMessage: function(message){
  93.                 return unescape(message);
  94.         },
  95.  
  96.         notify: function(pipe){
  97.                 pipe.els.tab.addClass('new_message');
  98.         },
  99.  
  100.         scrollMsg: function(pipe){
  101.                 var scrollSize = pipe.els.message.getScrollSize();
  102.                 pipe.els.message.scrollTo(0,scrollSize.y);
  103.         },
  104.  
  105.         writeMessage: function(pipe, message, sender){
  106.                 //Append message to last message
  107.                 if(pipe.lastMsg && pipe.lastMsg.sender.properties.name == sender.properties.name){
  108.                         var cnt = pipe.lastMsg.el;
  109.                 }else{//Create new one
  110.                         //Create message container
  111.                         var msg = new Element('div',{'class':'ape_message_container'});
  112.                         var cnt = new Element('div',{'class':'msg_top'}).inject(msg);
  113.                         if(sender){
  114.                                new Element('div',{'class':'ape_user','text':sender.properties.name}).inject(msg,'top');
  115.                         }
  116.                         new Element('div',{'class':'msg_bot'}).inject(msg);
  117.                         msg.inject(pipe.els.message);
  118.                 }
  119.                 new Element('div',{
  120.                         'text':this.parseMessage(message),
  121.                         'class':'ape_message'
  122.                 }).inject(cnt);
  123.                 //Scroll message box
  124.                 this.scrollMsg(pipe);
  125.                 //Add message to logs
  126.                 /*
  127.                 if(pipe.logs.length>=this.options.logs_limit){
  128.                         pipe.logs.shift();
  129.                 }
  130.                 pipe.logs.push({'message':message,'sender':sender});
  131.                 */
  132.                 pipe.lastMsg = {sender:sender,el:cnt};
  133.                 //notify
  134.                 if(this.getCurrentPipe().getPubid()!=pipe.getPubid()){
  135.                         this.notify(pipe);
  136.                 }
  137.         },
  138.  
  139.         createUser: function(user, pipe){
  140.                 user.el = new Element('div',{
  141.                                 'class':'ape_user'
  142.                         }).inject(pipe.els.users);
  143.                 new Element('a',{
  144.                                 'text':user.properties.name,
  145.                                 'href':'javascript:void(0)',
  146.                                 'events': {
  147.                                 'click':
  148.                                         function(ev,user){
  149.                                                         if(!this.core.getPipe(user.pubid)){
  150.                                                                 user.pipe = {pubid:user.pubid,properties:user.properties};
  151.                                                                 var pipe = this.core.newPipe('uni', user);
  152.                                                         }
  153.                                                         this.setCurrentPipe(user.pubid);
  154.                                                 }.bindWithEvent(this,[user])
  155.                                 }
  156.                         }).inject(user.el,'inside');
  157.         },
  158.  
  159.         deleteUser: function(user, pipe){
  160.                 user.el.dispose();
  161.         },
  162.  
  163.         createPipe: function(type, pipe, options){
  164.                 if(type=='uni') this.setPipeName(pipe, options);
  165.  
  166.                 var tmp;
  167.  
  168.                 //Define some pipe variables to handle logging and pipe elements
  169.                 pipe.els = {};
  170.                 pipe.logs = new Array();
  171.  
  172.                 //Container
  173.                 pipe.els.container = new Element('div',{
  174.                                                         'class':'ape_pipe ape_none '
  175.                                                 }).inject(this.els.pipeContainer);
  176.  
  177.                 //Message container
  178.                 pipe.els.message = new Element('div',{'class':'ape_messages'}).inject(pipe.els.container,'inside');
  179.  
  180.                 //If pipe has a users list
  181.                 if(pipe.users){
  182.                         pipe.els.usersRight = new Element('div',{
  183.                                 'class':'users_right'
  184.                         }).inject(pipe.els.container);
  185.  
  186.                         pipe.els.users = new Element('div',{
  187.                                                          'class':'ape_users_list'
  188.                                                  }).inject(pipe.els.usersRight);;
  189.                 }
  190.                 //Add tab
  191.                 pipe.els.tab = new Element('div',{
  192.                         'class':'ape_tab unactive'
  193.                 }).inject(this.els.tabs);
  194.  
  195.                 tmp = new Element('a',{
  196.                                 'text':pipe.name,
  197.                                 'href':'javascript:void(0)',
  198.                                 'events':{
  199.                                         'click':function(pipe){
  200.                                                         this.setCurrentPipe(pipe.getPubid())
  201.                                                 }.bind(this,[pipe])
  202.                                         }
  203.                                 }).inject(pipe.els.tab);
  204.  
  205.                 //Hide other pipe and show this one
  206.                 this.setCurrentPipe(pipe.getPubid());
  207.                 /* Do not work anymore
  208.                 //If logs, lets create it
  209.                 if(options.logs && options.logs.length>0){
  210.                         var logs = options.logs;
  211.                         for(var i = 0; i<logs.length; i++){
  212.                                 this.writeMessage(pipe,logs[i].message,logs[i].sender);
  213.                         }
  214.                 }
  215.                 */
  216.         },
  217.  
  218.         createChat: function(){
  219.                 this.els.pipeContainer = new Element('div',{'id':'ape_container'});
  220.                 this.els.pipeContainer.inject(this.options.container);
  221.  
  222.                 this.els.more = new Element('div',{'id':'more'}).inject(this.options.container,'after');
  223.                 this.els.tabs = new Element('div',{'id':'tabbox_container'}).inject(this.els.more);
  224.                 this.els.sendboxContainer = new Element('div',{'id':'ape_sendbox_container'}).inject(this.els.more);
  225.  
  226.                 this.els.sendBox = new Element('div',{'id':'ape_sendbox'}).inject(this.els.sendboxContainer,'bottom');
  227.                 this.els.sendboxForm = new Element('form',{
  228.                                                                 'events':{
  229.                                                                         'submit':function(ev){
  230.                                                                                         ev.stop();
  231.                                                                                         var val = this.els.sendbox.get('value');
  232.                                                                                         if(val!=''){
  233.                                                                                                 this.getCurrentPipe().send(val);
  234.                                                                                                 this.els.sendbox.set('value','');
  235.                                                                                         }
  236.                                                                                 }.bindWithEvent(this)
  237.                                                                         }
  238.                                 }).inject(this.els.sendBox);
  239.                 this.els.sendbox = new Element('input',{
  240.                                                         'type':'text',
  241.                                                         'id':'sendbox_input',
  242.                                                         'autocomplete':'off'
  243.                                                 }).inject(this.els.sendboxForm);
  244.                 this.els.send_button = new Element('input',{
  245.                                                         'type':'button',
  246.                                                         'id':'sendbox_button',
  247.                                                         'value':''
  248.                                                 }).inject(this.els.sendboxForm);
  249.         },
  250.  
  251.         restoreEnd: function(){
  252.                 this.core.getSession('currentPipe',function(resp){
  253.                         if(resp.raw=='SESSIONS') this.setCurrentPipe(resp.datas.sessions.currentPipe);
  254.                 }.bind(this));
  255.         },
  256.  
  257.         reset: function(){
  258.                 this.core.clearSession();
  259.                 if(this.els.pipeContainer){
  260.                         this.els.pipeContainer.dispose();
  261.                         this.els.more.dispose();
  262.                 }
  263.                 this.core.initialize(this.core.options);
  264.         }
  265. });
  1. //
  2. // nickname.js
  3. //
  4.  
  5. var userlist = new $H;
  6.  
  7. Ape.registerHookCmd("connect", function(params, cmd) {
  8.  
  9.         if (!$defined(params.name)) return 0;
  10.         if (userlist.has(params.name.toLowerCase())) return ["005", "NICK_USED"];
  11.         if (params.name.length > 16 || params.name.test('[^a-zA-Z0-9]', 'i')) return ["006", "BAD_NICK"];
  12.  
  13.        
  14.         cmd.user.setProperty('name', params.name);
  15.        
  16.         return 1;
  17. });
  18.  
  19. Ape.addEvent('adduser', function(user) {
  20.         userlist.set(user.getProperty('name').toLowerCase(), true);    
  21. });
  22.  
  23. Ape.addEvent('deluser', function(user) {
  24.         userlist.erase(user.getProperty('name').toLowerCase());
  25. });