Nodejs + express to build a multi-person chat room step, nodejsexpress

Source: Internet
Author: User
Tags emit install node

Nodejs + express to build a multi-person chat room step, nodejsexpress
Preface

This article is mainly a process in which I spent a few days as a trainer to write a tutorial while learning node. This is suitable for students who have a lot of theoretical knowledge about node and have little practical experience. Now let's get started!

Preparations

Create a folder chatroom

Enter the following command on the terminal. npm will automatically generate a package. json file for you to install node and npm on the official website.

Install express and socket. io

The package. json file is as follows:

//package.json{ "name": "chatroom", "version": "1.0.0", "description": "A simple chatroom", "main": "index.js", "scripts": {  "test": "echo \"Error: no test specified\" && exit 1" }, "repository": {  "type": "git",  "url": "git+https://github.com/ddvdd008/chatroom.git" }, "keywords": [  "chatroom",  "nodejs",  "express" ], "author": "ddvdd", "license": "ISC", "bugs": {  "url": "https://github.com/ddvdd008/chatroom/issues" }, "homepage": "https://github.com/ddvdd008/chatroom#readme"}

Install express and socket. io

npm install express --save npm install socket.io --save 

Automatically add dependency for package. json

"dependencies": { "express": "^4.16.2", "socket.io": "^2.0.4"}

Because we use the express framework to write back-end services and use socket. io (Socket. io is actually the parent set of WebSocket, Socket. io encapsulates methods such as WebSocket and polling, and he will select a method for communication based on the situation .) To establish a persistent link between the client and the server to facilitate communication.

The preparation work is almost done here. Next we will start to implement it step by step.

Build a web Server

Express creation Service

If you have learned node, you should be familiar with it. Using http. createServer, you can simply create a server. This time we use express to create a service. Create an app. js in the project root directory.

/*** Created by ddvdd on 2018-02-07. */const express = require ('express '); const app = express (); // create an express instance and assign it to the app. Const fs = require ('fs'); // This is the node file reading module used to read the file const path = require ('path '); // This is the path processing module of node. You can format the Path app. listen (3000, () => {console. log ("server running at 127.0.0.1: 3000"); // indicates listening to port 3000, and then executing the callback function to output it on the console .}); /*** App. get (): a middleware in express that is used to match get requests. Simply put, node processes the request route. For different url requests, different apps are allowed. get () to process * '/': it matches the get request's root route '/', that is, 127.0.0.1: 3000/, and it matches * req request object with table browser, res indicates the returned object of the server */app. get ('/', (req, res) => {res. redirect ('/chat.html'); // The redirection function of express. If the browser requests the root route '/', the browser redirects it to '123. 0.0.1: 3000/chat.html 'in the route});/*** the matching result here is that/chat.html is the redirected path above. */App. get ('/chat.html', (req, res) => {fs. readFile (path. join (_ dirname ,'. /public/chat.html '), function (err, data) {// read the file. The file path and callback function are input in readFile. path is used here. join () format the path. If (err) {console. error ("reading chat.html error", err); // res. send ('4 0 4'); // if an error occurs, return the 404} else {res to the browser. end (data); // The data here is the callback function parameter. The read data has been passed to the data variable of the callback function in readFile.} // We upload data to the browser, that is, to pass the html file to the browser })});

After reading this, you will say that this express framework is not that easy. The simplest method of sending a single page is to bring http to node. createServer is not much different from ELE. Me, and it is quite troublesome. So far, I am not trying to make it easy for you to understand ~ Express provides a very powerful middleware to help us host static resource files. Here we will implement it:

App. use ('/', express. static (path. join (_ dirname, './public'); // you can do it in one sentence.

Replace the original:

App. get ('/chat.html', (req, res) => {fs. readFile (path. join (_ dirname ,'. /public/chat.html '), function (err, data) {if (err) {console. error ("reading chat.html error", err); res. send ('4 0 4');} else {res. end (data );}})});

_ Dirname indicates the absolute path of the current file. Therefore, we use path. join to add the absolute path of app. js and public to get the absolute path of public. Using path. join is to avoid strange paths such as././public. express. static helps us host static resources in the public folder. Any path with 127.0.0.1: 3000/XXX/AAA will go to the public folder to find the AAA file in the XXX folder and send it to the browser.

Now let's take a look at this code to see if it is a lot of introduction. If you know more about what app. use () has done, you can go here.

Socket. io creates a link between the client and the server

After creating the above service, we need to reference socket. io so that the client and the server can establish a long-term link. We will transform app. js as follows:

/*** Created by ddvdd on 2018-02-07. */const express = require ('express '); const app = express (); // create an express instance and assign it to the app. Const server = require ('HTTP '). server (app); const io = require ('socket. io ') (server); // Add the socket listener to the app setting module. These two sentences cannot be understood. on the io official website, go to the const path = require ('path'); // This is the path processing module of node. You can format the path server. listen (3000, () => {console. log ("server running at 127.0.0.1: 3000"); // indicates listening to port 3000, and then executing the callback function to output it on the console. });...... App. use ('/', express. static (path. join (_ dirname ,'. /public '); // you can do it in one sentence. /* Socket */io. on ('connection', (socket) =>{// listen for Client connection events });

O. on indicates listening to an event. When this event occurs, the callback function is triggered. 'Connection' is an event name, which has been defined and will be triggered as long as the user connects. Now the app. js is basically complete. We will execute it in the root directory:

Node app. js

>

Now visit http: // 127.0.0.1: 3000/static/chat.html:

Ah? Nothing... That's not nonsense! We have no url request for the corresponding static resources!

Add static html

Create a new chat.html file in the publicfolder of the project root directory:

<! DOCTYPE html> 

Now let's refresh the page. You can see that the page appears:

>

In fact, the most simple project for collaboration between browsers and web servers has been completed. We will continue to improve the page and add business functions to the backend server to implement multi-person chat rooms.

Basic functions

For the login function, we need a user name (no password), which must be stored on the client server. The user name is required for each transmission. Otherwise, you do not know who sent the message.

For group chat, we need to distinguish information from each other.

Login implementation

Login Page Reconstruction

The basic logon interface consists of a user name input box and a logon button:

// Chat.html <! DOCTYPE html> 

Simply add some styles and the static page is complete. Refresh the page:

Login Page Interaction

Half written yesterday afternoon... The Department suddenly went to the group building party and had to submit code in a hurry. I came to the company early this morning to continue providing code for you.

When a user accesses the server and successfully logs on to the server, the server stores the user information in an array, save it on the server. Note that the server will verify the user's login username, and the verification result will be returned to the client. The client will verify the result and change whether the current page enters the chat page.

The above server and client interaction are through socket. io to achieve communication, front-end business interaction we use jquery here to achieve, in the public folder to create a new js folder, download jquery-3.2.1.min.js, new main. js. Then introduce the required sdk to chat.html:

<Script src = "js/jquery-3.2.1.min.js"> </script> <script src = "js/main. js "> </script> // socket. io official website requires the introduction of <script src = "/socket. io/socket. io. js "> </script>

After the sdk is introduced, we add the logon function to main's js:

// Main. js/*** Created by ddvdd on 2018-02-08. */$ (function () {const url = 'HTTP: // 127.0.0.1: 3000 '; let _ username = ''; let _ $ inputname = $ ('# name'); let _ $ loginButton = $ (' # loginbutton '); let socket = io. connect (url); // set the user name. When a user logs on, let setUsername = () =>{_ username =_$ inputname. val (). trim (); // get the user name entered by the user in the input box // determine whether the user name exists if (_ username) {socket. emit ('login', {username: _ username}); // if the user name exists When the table can be logged on, we will trigger the logon event, which is equivalent to telling the server that we are logged on} else {alert ('Enter the user name! ') ;}};/* Frontend event */_ $ loginButton. on ('click', function (event) {// click event of the listener button. If you click it, it indicates that the user wants to log on, and then runs the setUsername function setUsername ();}); /* socket. io logic */socket. on ('loginresult', (data) => {/*** if the username returned by the server is the same as the one you just sent, log on to the server * otherwise, a problem occurs, login denied */if (data. code = 0) {// login successful, switch to chat room page} else if (data. code = 1) {alert ('user logged on! ');} Else {alert ('logon failed! ') ;}})}); // App. js/*** Created by ddvdd on 2018-02-07. */const express = require ('express '); const app = express (); // create an express instance and assign it to the app. Const server = require ('HTTP '). server (app); const io = require ('socket. io ') (server); // Add the socket listener to the app setting module. These two sentences cannot be understood. on the io official website, go to the const path = require ('path'); // This is the path processing module of node. You can format the path const users = []; // used to save all user information. let usersNum = 0; // count the number of online logon users. server. listen (3000, () => {console. log ("server running at 127.0.0.1: 3000"); // indicates listening to port 3000, and then executing the callback function to output it on the console. });/*** App. get (): a middleware in express that is used to match get requests. Simply put, node processes the request route. For different url requests, different apps are allowed. get () to process * '/': it matches the get request's root route '/', that is, 127.0.0.1: 3000/, and it matches * req request object with table browser, res indicates the returned object of the server */app. get ('/', (req, res) => {res. redirect ('/static/chat.html'); // The redirection function of express. If the browser requests the root route '/', the browser redirects it to '123. 0.0.1: 3000/chat.html 'in route});/*** _ dirname indicates the absolute path of the current file, so we use path. join the app. the absolute path and public of js get the absolute path of public. * Path. join is used to avoid the strange path like././public * express. static, which helps us host static resources in the public folder. * Any path with 127.0.0.1: 3000/XXX/AAA will go to the public folder to find the AAA file in the XXX folder and send it to the browser. */App. use ('/static', express. static (path. join (_ dirname, './public'); // you can do it in one sentence. /* Socket */io. on ('connection', (socket) => {// listen to the client connection event socket. on ('login', (data) => {if (checkUserName (data) {socket. emit ('loginresult', {code: 1}); // code = 1 user logged on} else {// save this user's information to users in the array. push ({username: data. username, message: []}); socket. emit ('loginresult', {code: 0}); // code = 0 User Logon succeeded usersNum = users. length; console. log ('user $ {data. username} successfully logged on to the ddvdd chat room. current number of online logins: $ {usersNum} ') ;}}; // socket after the connection is disconnected. on ('disconnect', () => {// note that a Custom trigger is not required for this event, and the system automatically calls usersNum = users. length; console. log ('current number of online logins: $ {usersNum} ') ;}); // check whether the user has logged on to const checkUserName = (data) ==>{ let isExist = false; users. map (user) => {if (user. username = data. username) {isExist = true ;}}); return isExist ;}

For the above Code, you need to know the following:

  1. Socket. on indicates the listening event, followed by a callback function to receive the objects passed by the emit event.
  2. Socket. emit is used to trigger events and pass objects to the on listener events.
  3. The listener triggering events after the socket connection must be written in io. in the on ('connection') callback, because these events occur after the connection, even the disconnection event disconnect occurs in the connection event, and there is no connection status, which one is disconnected?
  4. Although the server only has an app. js is a file, but the information after different clients connect is different, so we must store some public information, such as an array of all login users, all information sent by all users is stored externally and cannot be stored in connecion.

Effect display:

Group chat function implementation

After writing the simple login function, let's talk about the most important function group of this project. First, let's take a look at the page. Because the function is simple, you can directly write the text on the login page without creating html to display the chat room. The class name changes to switch the display of the chat room.

Chat Room page Reconstruction

Next we will make corrections to chat.html:

<! DOCTYPE html> 

The chatbox container is added as a chat room, which contains a chat box for group chat and a text box for sending messages. Use the above loginResult callback to hide loginbox and display chatbox:

// Display the chat room interface let showChatRoom = () => {/*** 1. hide the logon box and cancel the events bound to it * 2. display the chat interface */$ ('# loginbox '). hide ('low'); _ $ loginButton. off ('click');/*** displays the chat interface and a line of text, welcome to */$ ('<div class = "title"> welcome $ {_ username} To ddvdd Chat Room </div> '). insertBefore ($ ("# content"); $ ("# chatbox "). show ('low ');}

Message event sending listening Mechanism

Chat must be triggered by the client, so sending information is triggered by the client and listened to by the server.

After the server monitors the event of sending information, it stores the information and broadcasts the event of successful sending of information to all clients to send the information to all clients.

Send message sendMessage event

// Main. js // send the message let sendMessage = function () {/*** to get the chat information in the input box. If it is not empty, trigger sendMessage * to send the information and user name in the past */let _ message = _ $ chattextarea. val (); if (_ message) {socket. emit ('sendmessage', {username: _ username, message: _ message});} else {alert ('Enter the message to send! ');}};... /* Chat events */_ $ chattextarea. on ('keyup', function (event) {if (event. keyCode = 13) {sendMessage (); _ $ chattextarea. val ('');}});

The server listens to sendMessage events.

// App. js/*** listens to sendMessage, and we get the message in the data transmitted by the client. */Socket. on ('sendmessage', (data) =>{ for (let _ user of users) {if (_ user. username = data. username) {_ user. message. push (data. message); // after storing the information, the receiveMessage is triggered to send the information to all browsers-broadcast event io. emit ('receivemessage', data); break ;}}});

We traverse the number of user groups on the server, locate the user, store the sent information, and trigger the receiveMessage event to broadcast to all browsers. sendMessage is written outside of connection and login, to do this, you must understand that sending messages is what you do when you connect, not when you log on.

Note that I am using io. emit, which is actually broadcast to all browsers, and socket. broadcast. emit will not broadcast to my browser.

The client listens to receiveMessage events.

// Main. jssocket. on ('receivemessage', (data) =>{/ ***** listen to messages broadcast by the server */showMessage (data );}) // display the message let showMessage = function (data) {// first judge whether the message was sent by itself, and then display if (data. username = _ username) {$ ("# content "). append ('<p class = 'self-message'> <span class = 'msg' >$ {data. message} </span> <span class = 'name' >:$ {data. username} </span> </p> ');} else {$ ("# content "). append ('<p class = 'other-message'> <span class = 'name' >$ {data. username }:</span> <span class = 'msg '>$ {data. message }</span> </p> ');}};

Here, we have completed the basic functions of our chat room. Let's take a look at the results! Open the three browsers and log on to the boss, the second, and the third respectively ~, I am a scum !".

Source Code address: https://github.com/ddvdd008/chatroom

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.