Chat with Web Sockets
In Live Web this week we learned about Web Sockets, which are TCP sockets in a thin HTML wrapper. To demonstrate Web Sockets we were tasked with implementing a demo chat application then developing it further on our own.
First I setup a server on Digital Ocean, which was pretty similar to past experience setting up a virtual server with AWS.
Ask for name once
The sample code we worked together on added an input field for “name”. To push a user to write a name I added code to require a name before showing the message field. Also the name field cannot be changed after entering.
Sender visibility
In attempt to show both messages sent and received by the user I made one change to the server.js code, adding a socket.emit() below the socket.broadcast.emit() function.
// Send it to all of the clients except sender socket.broadcast.emit('chatmessage', data); // Send it to sender socket.emit('chatmessage', data);
Styling
For styling I attempted to segment the interface with CSS, giving separate backgrounds to the message and reply areas.
Enter Key and Focus
Some other helpful changes included bringing text fields automatically in focus for the keyboard, and listening for an enter key as a submit button.
Code below from my index.html document.
<html> <head> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript"> var socket = io.connect(); var userName = ""; socket.on('connect', function() { console.log("Connected"); }); // Receive from any event socket.on('chatmessage', function (data) { console.log(data); // document.getElementById('messages').innerHTML += data.name + ": " + data.message + "<br/>"; }); function sendmessage (message, name) { var dataToSend = new Object(); // Use exisiting name if already set if(userName != ""){ dataToSend.name = userName; } else { // Otherwise set name from name field and hide name input for message input userName = name; dataToSend.name = name; document.getElementById('name').style.display = "none"; document.getElementById('nameLabel').style.display = "none"; document.getElementById('message').style.display = "block"; document.getElementById('message').focus(); document.getElementById('messageLabel').style.display = "block"; } dataToSend.message = message; // Send message if not empty if(dataToSend.message != ""){ console.log("chatmessage: " + dataToSend.message + ", from: " + dataToSend.name); socket.emit('chatmessage', dataToSend); } // Erase message field after sending document.getElementById('message').value = ""; }; </script> <style> .center { position: fixed; top: 50%; left: 50%; /* bring your own prefixes */ transform: translate(-50%, -50%); } .bottom { position: fixed; bottom: 0; left: 50%; /* bring your own prefixes */ transform: translate(-50%, -50%); width: 100%; } #messages_wrapper { background-color: lightgrey; width: 100%; height: 100%; position: fixed; bottom: 30px; left: 50%; /* bring your own prefixes */ transform: translate(-50%, -30px); } #messages { position: fixed; width: 100%; bottom: 0; left: 50%; /* bring your own prefixes */ transform: translate(-50%, 0); } #mybutton { position: fixed; width: 60px; height: 30px; border-radius: 5px; stroke-width: 0%; right: 5px; bottom: 5px; background-color: lightskyblue; } </style> </head> <body> <div> <div id="messages_wrapper"> <div id="messages"> </div> </div> <div id="messageInput" class="bottom"> <label for="message" id="messageLabel" style="display:none;">Message:</label> <input type="text" id="message" name="message" style="display:none;" autofocus> <label for="name" id="nameLabel">Name:</label> <input type="text" id="name" name="name" autofocus> <input type="submit" id="mybutton" value="send" onclick="sendmessage(document.getElementById('message').value, document.getElementById('name').value);"> </div> </div> <script> // Submit name on "enter" key press var nameInput = document.getElementById("name"); nameInput.addEventListener("keyup", function(event) { if (event.keyCode === 13) { event.preventDefault(); document.getElementById("mybutton").click(); } }); var messageInput = document.getElementById("message"); messageInput.addEventListener("keyup", function(event) { if (event.keyCode === 13) { event.preventDefault(); document.getElementById("mybutton").click(); } }); </script> </body> </html>