Socket Io Chat Homework
In this tutorial, we will be learning how to build a simple real-time chat application using Node, Express, and Socket.io. Our chat app will support custom usernames, join and leave messages, and of course the messages themselves, all in real-time. Here is a look at the finished app:Socket.io running on our Express-powered Node app.Full chat including joining and leaving.Before we dive in, make sure you meet the prerequisites for this tutorial:PrerequisitesBasic JavaScript knowledge is needed. If you need a refresher, check out our class on JavaScript.Node and NPM installed. If you don't have them installed, follow our how to install Node guide.Being familiar with HTML and CSS helps but is not needed as both will be provided with no changes needed.
socket io chat homework
Create a folder anywhere you'd like to serve as the root directory for your app. Navigate to that folder and initialize a new project by runningnpm initFeel free to enter in whatever information you'd like. After that finishes running, you will be left with a file called package.json. Install express by running this command:npm install -save expressNow let's create a file for Node to run as our server. Create a file called index.js and put this in it:import express from "express";import * as http from 'http';const app = express();const http = http.Server(app);const port = process.env.PORT 3000;app.get("/", function(req, res) res.sendFile(__dirname + "/index.html"););http.listen(port, function() console.log("Listening on *:" + port););With these few lines of code, we are doing quite a number of things. We are using express to serve up a static index.html file to the browser whenever it detects a GET request at the root (/), and then telling our server to listen to the port we defined. You can run the server right now by doing either npm run start or node index.js, however since we haven't started on index.html, nothing will happen.How the server looks when you run it.Creating index.htmlLet's create index.html to serve as the file we get from the server. Place this markup inside: Real-time Chat App Send This is a basic file that sets up the markup for our chatbox and input form. For simplicity's sake, we will incorporate both our styles and JavaScript code in this file. You can always put them in separate files if you want though.Here are all the styles you will need:body margin: 0; font-family: sans-serif;form position: fixed; bottom: 0; left: 0; width: 100%; display: flex; box-sizing: border-box; padding: 0.25rem;form input border: 0; padding: 0.5rem; width: 100%; outline: 0; margin-right: 0.5rem; border-radius: 0.25rem; background: #ccc;form button width: 6rem; background-color: #1b8c00; color: white; border: none; padding: 0.5rem; cursor: pointer; border-radius: 0.25rem; text-transform: uppercase;form button:hover background-color: #166d01;.messages margin: 0; padding: 0; margin-bottom: 3rem;.messages li padding: 0.5rem;.messages li:nth-child(odd) background: #eee;And here is the start of the JavaScript:const form = document.querySelector("form");const input = document.querySelector(".input");const messages = document.querySelector(".messages");const username = prompt("Please enter a username: ", "");form.addEventListener("submit", function(event) event.preventDefault(); addMessage(username + ": " + input.value); input.value = ""; return false;, false);addMessage("You have joined the chat as '" + username + "'.");function addMessage(message) const li = document.createElement("li"); li.innerHTML = message; messages.appendChild(li); window.scrollTo(0, document.body.scrollHeight);The code here is really simple. The first three assignments are just querying the page for the form, input button, and our messages list. The fourth one is the prompt that asks you what username you'd like to use. After that we attach a listener to prevent the form from submitting, add the message we sent by calling the addMessage function, then we reset the value of the input so that we can use it for the next message.The addMessage function takes a string as a parameter and uses it to set the contents of a brand new li element. That new element is then appended to the messages list. Finally, we scroll to the bottom of the body so that new messages are always in view.The entire file should look something like this: Real-time Chat App body margin: 0; font-family: sans-serif; form position: fixed; bottom: 0; left: 0; width: 100%; display: flex; box-sizing: border-box; padding: 0.25rem; form input border: 0; padding: 0.5rem; width: 100%; outline: 0; margin-right: 0.5rem; border-radius: 0.25rem; background: #ccc; form button width: 6rem; background-color: #1b8c00; color: white; border: none; padding: 0.5rem; cursor: pointer; border-radius: 0.25rem; text-transform: uppercase; form button:hover background-color: #166d01; .messages margin: 0; padding: 0; margin-bottom: 3rem; .messages li padding: 0.5rem; .messages li:nth-child(odd) background: #eee; Send const form = document.querySelector("form"); const input = document.querySelector(".input"); const messages = document.querySelector(".messages"); const username = prompt("Please enter a username: ", ""); form.addEventListener("submit", function(event) event.preventDefault(); addMessage(username + ": " + input.value); input.value = ""; return false; , false); addMessage("You have joined the chat as '" + username + "'."); function addMessage(message) const li = document.createElement("li"); li.innerHTML = message; messages.appendChild(li); window.scrollTo(0, document.body.scrollHeight); Now if you were to head on over to localhost:3000, your running server should now serve you this file. Upon page load, you should get a prompt asking you to enter your desired username. After that, you should see the join message with your desired username.Choosing your username.Entering chat.Sending a message.If you see this, you have done everything correctly so far!
Four applications are presented in order of increasing complexity:A trivial date server and client, illustrating simple one-way communication. The server sends data to the client only.A capitalize server and client, illustrating two-way communication, and server-side threads to more efficiently handle multiple connections simultaneously.A two-player tic tac toe game, illustrating a server that needs to keep track of the state of a game, and inform each client of it, so they can each update their own displays.A multi-user chat application, in which a server must broadcast messages to all of its clients.These applications communicate insecurely.None of these applications even try to secure communication. All data is sent between hosts completely in the clear. The goal at this point is to illustrate the most basic applications and how they use transport-level services. In real life, use a secure sockets layer.A Trivial Sequential ServerThis is perhaps the simplest possible server. It listens on port 59090. When a client connects, the server sends the current datetime to the client. The connection socket is created in a try-with-resources block so it is automatically closed at the end of the block. Only after serving the datetime and closing the connection will the server go back to waiting for the next client.DateServer.javaimport java.io.IOException;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.Date;/** * A simple TCP server. When a client connects, it sends the client the current * datetime, then closes the connection. This is arguably the simplest server * you can write. Beware though that a client has to be completely served its * date before the server will be able to handle another client. */public class DateServer public static void main(String[] args) throws IOException try (var listener = new ServerSocket(59090)) System.out.println("The date server is running..."); while (true) try (var socket = listener.accept()) var out = new PrintWriter(socket.getOutputStream(), true); out.println(new Date().toString()); Discussion:
This next server receives lines of text from a client and sends back the lines uppercased. It efficiently handles multiple clients at once: When a client connects, the server spawns a thread, dedicated to just that client, to read, uppercase, and reply. The server can listen for and serve other clients at the same time, so we have true concurrency.CapitalizeServer.javaimport java.io.IOException;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.Scanner;import java.util.concurrent.Executors;/** * A server program which accepts requests from clients to capitalize strings. * When a client connects, a new thread is started to handle it. Receiving * client data, capitalizing it, and sending the response back is all done on * the thread, allowing much greater throughput because more clients can be * handled concurrently. */public class CapitalizeServer /** * Runs the server. When a client connects, the server spawns a new thread to do * the servicing and immediately returns to listening. The application limits * the number of threads via a thread pool (otherwise millions of clients could * cause the server to run out of resources by allocating too many threads). */ public static void main(String[] args) throws Exception try (var listener = new ServerSocket(59898)) System.out.println("The capitalization server is running..."); var pool = Executors.newFixedThreadPool(20); while (true) pool.execute(new Capitalizer(listener.accept())); private static class Capitalizer implements Runnable private Socket socket; Capitalizer(Socket socket) this.socket = socket; @Override public void run() System.out.println("Connected: " + socket); try var in = new Scanner(socket.getInputStream()); var out = new PrintWriter(socket.getOutputStream(), true); while (in.hasNextLine()) out.println(in.nextLine().toUpperCase()); catch (Exception e) System.out.println("Error:" + socket); finally try socket.close(); catch (IOException e) System.out.println("Closed: " + socket); Discussion: