Nodejs implements chat rooms based on socket. io
Because the socket. io module is used for the web video Live project to be implemented later, I spent some time studying it and made some improvements by referring to the online code. I wrote a chat room code myself. I have to admit that the backend fact push capability is a little powerful. This is something I 've been worried about with php before. The following is a brief introduction to my project, along with nodejs.
In fact, before reading the code written by others, I never knew what node. js was doing. I didn't understand it until I got real access to it. It could also be regarded as a server code, A wide range of third-party libraries make it extremely powerful. It can enable the server directly through the command line like golang's beego, but it needs to use the express module. The method for Loading modules is similar to php, as shown below:
Var express = require ('express '); // reference express
To enable a server, you only need the following lines of code:
Var express = require ('express '); // reference expressvar app = express (); var server = require ('http '). server (app); // listen to the server to start the Server. listen (3000, function () {console. log (Express server listening on port + app. get ('Port '));});
After the server is enabled successfully, use console. log to print messages on the command line, which is convenient.
Next, we should define the route. In fact, nodejs has a routing module. However, I have not studied the specific functions of the module, and I only borrowed code from others to write the basic routing, the formula is as follows:
app.set('views', __dirname + '/views');app.get('/', function(req, res) {//res.send('hello world');res.sendFile(app.get(views) + '/login.html');//res.redirect('/login');});
Req is the request, and res is the response, which is similar to javaweb. Res. send directly outputs the string content to the page, while sendFile outputs the content of the specified file to the page, and redirect is the redirection. If I enable the server on port 3000, the above Code stipulates that when I access localhost: 3000/through the get method, the contents of views/login.html will be output to the page, in fact, the page views/login.html is accessed. In app. get, get is the get method. Similarly, to write the post request interface, use app. post. Note: This app object is the express object defined at the beginning of the article.
After the introduction, we will introduce the template. Since nodejs can be developed as a server language, the template module is indispensable. Of course, nodejs has many template modules. Here I only know about the ejs module. I will only introduce this.
The call method is as follows:
App. set (view engine, ejs); // The homepage app of the chat room. get ('/Index', function (req, res) {res. render (index, {user: req. session. user });});
Call res. the render method is used to pass values to the page. The first parameter is the template page name, that is, views/index. ejs (note that the suffix is ejs). The second parameter is the attached data. Since it is js, the attached data is naturally json data under js. Note: In nodejs, views and views appear to have rules. The app defines the page path. set ('view', _ dirname + '/view'); the program runs successfully, while the app. set ('view', _ dirname + '/view'); an error will be reported, and the cause of the error is forgotten. I checked the answers in the English forum to find out the problem, it is best to use views when defining the page path.
It is also convenient to call on the template page, just <% = user %>. As follows:
Id = user/> req. session. user is the session Module I use. Because my chat room has a login page, by the way, I am familiar with the session module. The call method is as follows:
Var session = require ('express-session'); // if you want to use a session, you must separately include this module app. use (session ({secret: 'scumvirus ', name: 'sv _ chat', // The name here is the cookie name. The default cookie name is connect. sidcookie: {maxAge: 3600000}, // set maxAge to 3600000 ms, that is, after 1 h, the session and the corresponding cookie expire. resave: false, saveUninitialized: true ,})); // set sessionreq. session. user = ScumVirus; // obtain sessionvar name = req. session. user;
Nodejs also provides an encryption module that can easily encrypt strings. I generally use 32-bit md5 encryption, and only introduce how to obtain 32-bit md5 encryption, as follows:
Var crypto = require ('crypto'); // encrypt // obtain the md5 encrypted value var getMD5 = function (str) {var md5 = crypto. createHash ('md5'); md5.update (str); var d = md5.digest ('hex'); return d ;}
In addition, I also used the mysql module to connect to the mysql database and implement registration and login at the front end. The call is as follows:
Var mysql = require (mysql); // database module // connect to the database var connPool = mysql. createPool ({host: '2017. 0.0.1 ', // host user: 'root', // MySQL authentication Username password: 'admin', // MySQL authentication username port: '123', // port number database: 'sv _ chat', // database waitForConnections: true, // when the connection pool is not connected or exceeds the maximum limit, it is set to true and the connection is put into the queue // connectionLimit: 10, // connection limit}); // obtain the user information based on the user var getUserById = function (name, callback) {// execute the SQL statement var SQL = 'select * from sv_user where name =? '; Var params = [name]; connPool. query (SQL, params, function (err, result) {if (err) {console. log ('[select error]-', err. message); return;} return callback (result [0]);} // Add a new user var addUser = function (params, callback) {// execute the SQL statement var SQL = 'insert into sv_user ('name', 'pwd', 'email ', 'phone', 'create _ Time ') values (?,?,?,?,?) '; ConnPool. query (SQL, params, function (err, result) {if (err) {console. log ('[insert error]-', err. message); return callback (false);} else {console. log ('insert ID: ', result. insertId); return callback (true );}});}
If you are interested, you can print the query result in json format, including insetId and affectedRows, which is almost the same as php. However, the only pitfall point is that the query database is executed asynchronously. If you want to return the query result to the front-end page, the value may not be obtained until the callback method is used. I have also introduced online that linear execution can be performed, but I have not studied it carefully. I understand callback quickly and I will first use the callback function for processing.
The last is the most critical communication phase. The background code of the socket. io module is as follows:
Var io = require ('socket. io '). listen (server); // socket io module // WebSocket connection listening io. on ('connection', function (socket) {// socket. emit ('open', onlineMember); // notifies the client that it has been connected // print the handshake information // console. log (socket. handshake); // construct the client object var client = {name: '',} // listen to the message event // login event socket. on ('login', function (name) {var time = getTime (); client. name = name; var index = getArrIndex (name, onlineMember); if (index =-1) {onlineMember. push (client. name); console. log (time ++ client. name + login);} var obj = {time: time, author: client. name, text: '', type: 'login', member: onlineMember}; socket. emit ('system', obj); socket. broadcast. emit ('system', obj) ;}); // message event socket. on ('message', function (msg) {var obj = {time: getTime (),}; obj ['msg '] = msg; obj ['author'] = client. name; obj ['type'] = 'message'; // Response message (can be omitted) socket. emit ('message', obj); // broadcast messages to other users socket. broadcast. emit ('message', obj) ;}); // listens to the exit event socket. on ('disconnect', function () {var index = getArrIndex (client. name, onlineMember); if (index>-1) {onlineMember. splice (index, 1);} var time = getTime (); var obj = {time: time, author: client. name, text: '', type: 'loginout', member: onlineMember}; console. log (time ++ client. name + loginout); // The broadcast user has exited the socket. broadcast. emit ('system', obj );});});
Front-end connection code:
<Script src =/socket. io/socket. io. js> </script> <script> // create a websocket connection socket = io. connect ('HTTP: // localhost: 100'); var userName = $ (# user ). val (); socket. emit ('login', userName); </script>
Socket. emit can be understood as A two-way communication method. If Client A is connected to server B, then A calls the emit method, B receives the message, and B calls the emit method, then A receives the message. And socket. broadcast. the emit method is broadcast. If the client A, B, and C are connected to the server D at the same time, A sends A message to D through emit, and D calls the broadcast method after receiving the message, then B, C receives the message, while A does not. Login is a custom push message type, and message is a type defined by the plug-in itself. The front-end can use socket. send (msg) is triggered. disconnect is also a type defined by the plug-in and called when the client is disconnected.