Rumah > Tutorial CMS > WordTekan > teks badan

Sembang langsung menggunakan NodeJS, Socket.io dan ExpressJS

王林
Lepaskan: 2023-08-29 12:49:14
asal
1037 orang telah melayarinya

Sembang langsung menggunakan NodeJS, Socket.io dan ExpressJS

NodeJS membenarkan saya menulis kod hujung belakang dalam salah satu bahasa kegemaran saya: JavaScript. Ia adalah teknologi yang sempurna untuk membina aplikasi masa nyata. Dalam tutorial ini, saya akan menunjukkan kepada anda cara membina aplikasi sembang web menggunakan ExpressJS dan Socket.io.


Sediakan persekitaran

Sudah tentu, perkara pertama yang perlu dilakukan ialah memasang NodeJS pada sistem anda. Jika anda pengguna Windows atau Mac, anda boleh melawati nodejs.org dan memuat turun pemasang. Jika anda lebih suka Linux, saya syorkan anda merujuk pautan ini. Walaupun saya tidak akan menjelaskan perkara ini secara terperinci, jika anda menghadapi sebarang masalah pemasangan, saya berbesar hati untuk membantu;

Selepas memasang NodeJS, anda boleh menyediakan alatan yang anda perlukan.

  1. ExpressJS - Ini akan menguruskan pelayan dan respons kepada pengguna
  2. Jade - Enjin Templat
  3. Socket.io - membenarkan komunikasi masa nyata antara bahagian hadapan dan hujung belakang

Teruskan dan buat fail package.json dalam direktori kosong dengan kandungan berikut.

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

Dengan menggunakan konsol (dalam Windows - Command Prompt), navigasi ke folder anda dan jalankan:

npm install
Salin selepas log masuk

Dalam beberapa saat, anda akan memuat turun semua kebergantungan yang diperlukan ke dalam direktori node_modules.


Bangunkan bahagian belakang

Mari kita mulakan dengan pelayan ringkas yang akan menyediakan halaman HTML aplikasi, dan kemudian beralih ke bahagian yang lebih menarik: komunikasi masa nyata. Buat fail index.js menggunakan kod teras expressjs berikut:

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);
Salin selepas log masuk

Di atas, kami mencipta aplikasi dan menentukan portnya. Seterusnya, kami mendaftarkan laluan, yang dalam kes ini adalah permintaan GET yang mudah tanpa sebarang parameter. Pada masa ini, pengendali laluan hanya menghantar beberapa teks kepada pelanggan. Akhirnya, sudah tentu, di bahagian bawah, kami menjalankan pelayan. Untuk memulakan aplikasi, jalankan dari konsol:

node index.js
Salin selepas log masuk

Pelayan sedang berjalan, jadi anda sepatutnya boleh membuka http://127.0.0.1:3700/ dan lihat:

It works!
Salin selepas log masuk

Sekarang, daripada "ia berfungsi", kami harus menyediakan HTML. Mungkin lebih berfaedah untuk menggunakan enjin templat dan bukannya HTML biasa. Jade ialah pilihan yang bagus dan mempunyai integrasi yang hebat dengan ExpressJS. Inilah yang biasanya saya gunakan dalam projek saya sendiri. Buat direktori yang dipanggil tpl dan letakkan fail page.jade berikut ke dalamnya:

!!!
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')
Salin selepas log masuk

Sintaks Jade tidak rumit, namun, untuk panduan lengkap, saya syorkan anda merujuk kepada jade-lang.com. Untuk menggunakan Jade dengan ExpressJS kami memerlukan persediaan berikut.

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

Kod ini memberitahu Express lokasi fail templat anda dan enjin templat yang hendak digunakan. Semuanya menentukan fungsi yang akan mengendalikan kod templat. Setelah semuanya disediakan, kami boleh menggunakan kaedah .render objek response dan menghantar kod Jade kami kepada pengguna. response 对象的 .render 方法,并将我们的 Jade 代码发送给用户。

此时的输出并不特殊;无非是一个 div 元素(id 为 content 的元素),它将用作聊天消息的容器和两个控件(输入字段和按钮),我们将使用它们来发送消息。

因为我们将使用一个外部 JavaScript 文件来保存前端逻辑,所以我们需要通知 ExpressJS 在哪里寻找此类资源。创建一个空目录 public,并在调用 .listen 方法之前添加以下行。

app.use(express.static(__dirname + '/public'));
Salin selepas log masuk

到目前为止一切顺利;我们有一个成功响应 GET 请求的服务器。现在,是时候添加 Socket.io 集成了。更改此行:

app.listen(port);
Salin selepas log masuk

至:

var io = require('socket.io').listen(app.listen(port));
Salin selepas log masuk

上面,我们将 ExpressJS 服务器传递给了 Socket.io。实际上,我们的实时通信仍然会发生在同一端口上。

接下来,我们需要编写从客户端接收消息并将其发送给所有其他客户端的代码。每个 Socket.io 应用程序都以 connection 处理程序开始。我们应该有一个:

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

传递给处理程序的对象 socket 实际上是客户端的套接字。将其视为服务器和用户浏览器之间的连接点。连接成功后,我们发送 welcome 类型的消息,当然,还会绑定另一个将用作接收器的处理程序。结果,客户端应该发出一条名为 send 的消息,我们将捕获该消息。接下来,我们只需使用 io.sockets.emit 将用户发送的数据转发到所有其他套接字。

通过上面的代码,我们的后端已准备好向客户端接收和发送消息。让我们添加一些前端代码。


开发前端

创建 chat.js,并将其放置在应用程序的 public

Output pada ketika ini bukanlah sesuatu yang istimewa; ia tidak lebih daripada elemen div (yang mempunyai id content) yang akan berfungsi sebagai bekas untuk mesej sembang dan dua kawalan (medan input dan butang), kami akan menggunakannya untuk menghantar mesej.

🎜Oleh kerana kami akan menggunakan fail JavaScript luaran untuk memegang logik bahagian hadapan, kami perlu memberitahu ExpressJS di mana untuk mencari sumber tersebut. Buat direktori kosong awam dan tambah baris berikut sebelum memanggil kaedah .listen. 🎜
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 });
    };

}
Salin selepas log masuk
Salin selepas log masuk
🎜Setakat ini, kami mempunyai pelayan yang berjaya menjawab permintaan GET. Kini, tiba masanya untuk menambah integrasi Socket.io. Tukar baris ini: 🎜
head
    title= "Real time web chat"
    script(src='/chat.js')
    script(src='/socket.io/socket.io.js')
Salin selepas log masuk
Salin selepas log masuk
🎜Kepada: 🎜
.controls
    | Name: 
    input#name(style='width:350px;')
    br
    input#field(style='width:350px;')
    input#send(type='button', value='send')
Salin selepas log masuk
Salin selepas log masuk
🎜Di atas, kami menghantar pelayan ExpressJS ke Socket.io. Malah, komunikasi langsung kami masih akan berlaku di pelabuhan yang sama. 🎜 🎜Seterusnya, kita perlu menulis kod yang menerima mesej daripada pelanggan dan menghantarnya kepada semua pelanggan lain. Setiap aplikasi Socket.io bermula dengan pengendali sambungan. Kita sepatutnya mempunyai satu: 🎜
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 });
        }
    };

}
Salin selepas log masuk
Salin selepas log masuk
🎜Objek soket yang dihantar kepada pengendali sebenarnya adalah soket pelanggan. Anggap ia sebagai titik sambungan antara pelayan dan penyemak imbas pengguna. Setelah sambungan berjaya, kami menghantar mesej jenis selamat datang dan, sudah tentu, mengikat pengendali lain yang akan bertindak sebagai penerima. Akibatnya, pelanggan harus mengeluarkan mesej yang dipanggil hantar, yang akan kami tangkap. Seterusnya, kami hanya menggunakan io.sockets.emit untuk memajukan data yang dihantar oleh pengguna ke semua soket lain. 🎜 🎜Dengan kod di atas, bahagian belakang kami bersedia untuk menerima dan menghantar mesej kepada pelanggan. Mari tambahkan beberapa kod bahagian hadapan. 🎜 🎜 🎜Bangunkan bahagian hadapan🎜 🎜Buat chat.js dan letakkannya dalam direktori public aplikasi. Tampal kod berikut: 🎜
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 });
    };

}
Salin selepas log masuk
Salin selepas log masuk

我们的逻辑包装在 .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')
Salin selepas log masuk
Salin selepas log masuk

请注意,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')
Salin selepas log masuk
Salin selepas log masuk

接下来,在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 });
        }
    };

}
Salin selepas log masuk
Salin selepas log masuk

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

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

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

content.innerHTML = html;
content.scrollTop = content.scrollHeight;
Salin selepas log masuk

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

$("#content").scrollTop($("#content")[0].scrollHeight);
Salin selepas log masuk

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

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

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

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

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

sendButton.onclick = sendMessage = function() {
    ...
};
Salin selepas log masuk

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


结论

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

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

Atas ialah kandungan terperinci Sembang langsung menggunakan NodeJS, Socket.io dan ExpressJS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!