Home  >  Article  >  CMS Tutorial  >  Live chat using NodeJS, Socket.io and ExpressJS

Live chat using NodeJS, Socket.io and ExpressJS

王林
王林Original
2023-08-29 12:49:141007browse

Live chat using NodeJS, Socket.io and ExpressJS

NodeJS allows me to write backend code in one of my favorite languages: JavaScript. It is the perfect technology for building real-time applications. In this tutorial, I'll show you how to build a web chat application using ExpressJS and Socket.io.


Set up environment

Of course, the first thing to do is to install NodeJS on your system. If you are a Windows or Mac user, you can visit nodejs.org and download the installer. If you prefer Linux, I recommend you refer to this link. While I won't go into detail on this, if you run into any installation issues I'd be happy to help; just leave a comment below this article.

After installing NodeJS, you can set up the required tools.

  1. ExpressJS - This will manage the server and responses to the user
  2. Jade - Template Engine
  3. Socket.io - allows real-time communication between frontend and backend

Continue, create a package.json file in an empty directory containing the following content.

{
    "name": "RealTimeWebChat",
    "version": "0.0.0",
    "description": "Real time web chat",
    "dependencies": {
        "socket.io": "latest",
        "express": "latest",
        "jade": "latest"
    },
    "author": "developer"
}

By using the console (in Windows - Command Prompt), navigate to your folder and execute:

npm install

Within a few seconds, you will have all required dependencies downloaded into the node_modules directory.


Developing backend

Let’s start with a simple server that will serve the application’s HTML pages, and then move on to the more interesting part: real-time communication. Create an index.js file using the following core expressjs code:

var express = require("express");
var app = express();
var port = 3700;

app.get("/", function(req, res){
    res.send("It works!");
});

app.listen(port);
console.log("Listening on port " + port);

Above, we created an application and defined its port. Next, we register a route, which in this case is a simple GET request without any parameters. Currently, the route's handler just sends some text to the client. Finally, of course, at the bottom, we run the server. To initialize the application, execute from the console:

node index.js

The server is running, so you should be able to open http://127.0.0.1:3700/ and see:

It works!

Now, instead of "it works", we should provide HTML. It might be more beneficial to use a template engine instead of plain HTML. Jade is a great choice and has great integration with ExpressJS. This is what I usually use in my own projects. Create a directory called tpl and place the following page.jade file into it:

!!!
html
    head
        title= "Real time web chat"
    body
        #content(style='width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px #999; overflow-y: scroll;')
        .controls
            input.field(style='width:350px;')
            input.send(type='button', value='send')

The syntax of Jade is not complicated, however, for a complete guide, I recommend you to refer to jade-lang.com. In order to use Jade with ExpressJS we need to set up the following.

app.set('views', __dirname + '/tpl');
app.set('view engine', "jade");
app.engine('jade', require('jade').__express);
app.get("/", function(req, res){
    res.render("page");
});

This code tells Express where your template files are located and which template engine to use. It all specifies the function that will handle the template code. Once everything is set up, we can use the response object's .render method and send our Jade code to the user.

The output at this point is nothing special; it's nothing more than a div element (the one with the id content), which will serve as a container for the chat message and two controls (the input field and the button ), we will use them to send messages. p>

Because we will be using an external JavaScript file to hold the front-end logic, we need to tell ExpressJS where to look for such resources. Create an empty directory public and add the following lines before calling the .listen method.

app.use(express.static(__dirname + '/public'));

So far so good; we have a server that successfully responds to GET requests. Now, it's time to add Socket.io integration. Change this line:

app.listen(port);

to:

var io = require('socket.io').listen(app.listen(port));

Above, we passed the ExpressJS server to Socket.io. In fact, our live communication will still happen on the same port.

Next, we need to write the code that receives messages from the client and sends them to all other clients. Every Socket.io application starts with a connection handler. We should have one:

io.sockets.on('connection', function (socket) {
    socket.emit('message', { message: 'welcome to the chat' });
    socket.on('send', function (data) {
        io.sockets.emit('message', data);
    });
});

The object passed to the handler socket is actually the client's socket. Think of it as the connection point between the server and the user's browser. Once the connection is successful, we send a message of type welcome and, of course, bind another handler that will act as a receiver. As a result, the client should issue a message named send, which we will capture. Next, we simply use io.sockets.emit to forward the data sent by the user to all other sockets.

With the above code, our backend is ready to receive and send messages to the client. Let's add some front-end code.


Developing front-end

Create chat.js and place it in the public directory of your application. Paste the following code:

window.onload = function() {

    var messages = [];
    var socket = io.connect('http://localhost:3700');
    var field = document.getElementById("field");
    var sendButton = document.getElementById("send");
    var content = document.getElementById("content");

    socket.on('message', function (data) {
        if(data.message) {
            messages.push(data.message);
            var html = '';
            for(var i=0; i<messages.length; i++) {
                html += messages[i] + '<br />';
            }
            content.innerHTML = html;
        } else {
            console.log("There is a problem:", data);
        }
    });

    sendButton.onclick = function() {
        var text = field.value;
        socket.emit('send', { message: text });
    };

}

我们的逻辑包装在 .onload 处理程序中,只是为了确保所有标记和外部 JavaScript 均已完全加载。在接下来的几行中,我们创建一个数组,它将存储所有消息、一个 socket 对象以及一些 DOM 元素的快捷方式。同样,与后端类似,我们绑定一个函数,它将对套接字的活动做出反应。在我们的例子中,这是一个名为 message 的事件。当此类事件发生时,我们期望收到一个对象,data,其属性为 message。将该消息添加到我们的存储中并更新 content div。我们还包含了发送消息的逻辑。这非常简单,只需发出一条名为 send 的消息。

如果你打开http://localhost:3700,你会遇到一些错误弹出窗口。这是因为我们需要更新 page.jade 以包含必要的 JavaScript 文件。

head
    title= "Real time web chat"
    script(src='/chat.js')
    script(src='/socket.io/socket.io.js')

请注意,Socket.io 管理 socket.io.js 的交付。您不必担心手动下载此文件。

我们可以在控制台中使用 node index.js 再次运行我们的服务器并打开http://localhost:3700。您应该会看到欢迎消息。当然,如果你发送一些东西,应该显示在内容的div中。如果您想确保它有效,请打开一个新选项卡(或者更好的是,一个新浏览器)并加载应用程序。 Socket.io 的伟大之处在于,即使您停止 NodeJS 服务器它也能工作。前端将继续工作。一旦服务器再次启动,您的聊天也会正常。

在目前的状态下,我们的聊天并不完美,需要一些改进。


改进

我们需要做的第一个更改是消息的标识。目前,尚不清楚哪些消息是由谁发送的。好处是我们不必更新 NodeJS 代码来实现这一点。这是因为服务器只是转发 data 对象。因此,我们需要在那里添加一个新属性,并稍后读取它。在对 chat.js 进行更正之前,让我们添加一个新的 input 字段,用户可以在其中添加他/她的姓名。在 page.jade 中,更改 controls div:

.controls
    | Name: 
    input#name(style='width:350px;')
    br
    input#field(style='width:350px;')
    input#send(type='button', value='send')

接下来,在code.js中:

window.onload = function() {

    var messages = [];
    var socket = io.connect('http://localhost:3700');
    var field = document.getElementById("field");
    var sendButton = document.getElementById("send");
    var content = document.getElementById("content");
    var name = document.getElementById("name");

    socket.on('message', function (data) {
        if(data.message) {
            messages.push(data);
            var html = '';
            for(var i=0; i<messages.length; i++) {
                html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
                html += messages[i].message + '<br />';
            }
            content.innerHTML = html;
        } else {
            console.log("There is a problem:", data);
        }
    });

    sendButton.onclick = function() {
        if(name.value == "") {
            alert("Please type your name!");
        } else {
            var text = field.value;
            socket.emit('send', { message: text, username: name.value });
        }
    };

}

为了总结这些变化,我们:

  1. 为用户名的 input 字段添加了新快捷方式
  2. 稍微更新了消息的呈现方式
  3. 向对象添加了一个新的 username 属性,该属性将发送到服务器

如果消息数量过多,用户将需要滚动 div:

content.innerHTML = html;
content.scrollTop = content.scrollHeight;

请记住,上述解决方案可能不适用于 IE7 及更低版本,但没关系:IE7 是时候消失了。但是,如果您想确保支持,请随意使用 jQuery:

$("#content").scrollTop($("#content")[0].scrollHeight);

如果发送消息后输入字段被清除,那就太好了:

socket.emit('send', { message: text, username: name.value });
field.value = "";

最后一个无聊的问题是每次点击发送按钮。通过一点 jQuery,我们可以监听用户何时按下 Enter 键。

$(document).ready(function() {
    $("#field").keyup(function(e) {
        if(e.keyCode == 13) {
            sendMessage();
        }
    });
});

可以注册函数 sendMessage,如下所示:

sendButton.onclick = sendMessage = function() {
    ...
};

请注意,这不是最佳实践,因为它注册为全局函数。但是,对于我们在这里的小测试来说,一切都很好。


结论

NodeJS 是一项非常有用的技术,它为我们提供了巨大的力量和乐趣,特别是考虑到我们可以编写纯 JavaScript 的事实。正如您所看到的,仅用几行代码,我们就编写了一个功能齐全的实时聊天应用程序。非常整洁!

想要了解有关使用 ExpressJS 构建 Web 应用程序的更多信息?我们为您服务!

The above is the detailed content of Live chat using NodeJS, Socket.io and ExpressJS. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn