Link Search Menu Expand Document

8. A demo chat application

The following is a listing for a super simple chat application. Update your code with the following and have a play! Note, the source code for this application has been taken and adapted from here: https://www.tutorialspoint.com/socket.io/socket.io_chat_application.htm (well worth going through their tutorial to get another angle).

<!DOCTYPE html>
<html>
   <head>
     <title>Socket.io-Lucee: Tutorial (Chat demo)</title>
     <script src="https://cdn.socket.io/socket.io-2.3.1.js"></script>
     <script>
      var socket = io( "127.0.0.1:3000" );
      function setUsername() {
       socket.emit('setUsername', document.getElementById('name').value);
      };
      var user;
      socket.on('userExists', function(data) {
       document.getElementById('error-container').innerHTML = data;
      });
      socket.on('userSet', function(username) {
       user = username;
       document.body.innerHTML = '<input type = "text" id = "message">\
       <button type = "button" name = "button" onclick = "sendMessage()">Send</button>\
       <div id = "message-container"></div>';
      });
      function sendMessage() {
       var msg = document.getElementById('message').value;
       if(msg) {
        socket.emit('msg', {message: msg, user: user});
       }
      }
      socket.on('newmsg', function(data) {
       if(user) {
        document.getElementById('message-container').innerHTML += '<div><b>' +
           data.user + '</b>: ' + data.message + '</div>'
       }
      })
     </script>
   </head>


   <body>
    <div id = "error-container"></div>
    <input id = "name" type = "text" name = "name" value = ""
     placeholder = "Enter your name!">
    <button type = "button" name = "button" onclick = "setUsername()">
     Let me chat!
    </button>
   </body>
</html>
component {

  this.name = "socket.io-lucee test harness application";

  processingdirective preserveCase="true";

  public void function onRequest( required string requestedTemplate ) output=true {
    // each request, check to see if we need to setup our Server and listeners
    reloadCheck();

    include template=arguments.requestedTemplate;
  }

// private helpers
  private void function setupListeners() {
    var users = application.users = [];
    var userMaps = application.userMaps = {};
    var io = application.io;

    // note: this not thread safe - just a rough demo

    io.on( "connect", function( socket ){
      socket.on('setUsername', function( username ) {
        if( ArrayFindNoCase( users, username ) ) {
          socket.emit('userExists', username & ' username is taken! Try some other username.');
        } else {
          ArrayAppend( users, username );
          userMaps[ socket.getId() ] = username;
          socket.emit('userSet', username );
        }
      });

      socket.on('msg', function(msg) {
        io.sockets.emit('newmsg', msg);
      });

      socket.on('disconnect', function() {
        if ( Len( userMaps[ socket.getId() ] ?: "" ) ) {
          ArrayDelete( users, userMaps[ socket.getId() ] );
        }
      } );
    } );
  }


  private void function reloadCheck() {
    // Setup our server and listeners if either`?fwreinit=true` is 
    // present in the URL, or if it has not yet been setup
    if ( !StructKeyExists( application, "io" ) || ( url.fwreinit ?: "" ) == "true" ) {
      shutdownServer();
      initServer();
      setupListeners();
    }
  }

  private void function initServer() {
    // create and start the server on default port, 3000
    application.io = new socketiolucee.models.SocketIoServer( enableCorsHandling=true );
  }

  private void function shutdownServer() {
    if ( StructKeyExists( application, "io" ) ) {
      application.io.close();
      StructDelete( application, "io" );
    }

  }

}

Summary

The above listing demonstrates a few concepts. Have a play and make use of namespaces and rooms along the way.

Hopefully this gives you a broad understanding of the Socket.IO library and how to use it on both the client side and also from your Lucee applications with Socket.io-lucee.