自制chatroom
本文是Microsoft的Web开发技术系列的一部分。 感谢您支持使SitePoint成为可能的合作伙伴。
这个Node.js教程系列将帮助您构建完全部署在云中的由Node.js驱动的实时聊天室Web应用程序。 在本系列中,您将学习如何在Windows计算机上设置Node.js (如果在Mac上则仅学习概念),如何使用Express开发Web前端,如何将Node.js Express应用程序部署到Azure ,如何使用Socket.IO添加实时层,以及如何一起部署所有实时层。
本教程将使用可选的Visual Studio和Visual Studio插件的Node.js工具作为开发环境。 我提供了两个工具的免费下载链接。 这是中级文章的初学者–您应该了解HTML5和JavaScript。
第2部分–欢迎使用带有Node.js和Azure的Express
第3部分–使用Node.js,Mongo和Socket.IO构建后端
第3部分–使用Node.js,Socket.IO和Mongo构建聊天室后端
欢迎使用动手Node.js教程系列的第3部分:构建一个由Node.js驱动的聊天室Web应用程序。 在本期中,我将向您展示如何使用现有的基于Express的Node.js应用程序来创建具有WebSocket支持的聊天室后端。
什么是WebSocket? 什么是Socket.IO?
WebSocket是一种协议,旨在允许Web应用程序在Web浏览器和Web服务器之间通过TCP创建全双工通道(即具有双向通信)。 它与HTTP完全兼容,并使用TCP端口号80。WebSocket允许Web应用程序成为实时应用程序,并支持客户端和服务器之间的高级交互。 几种浏览器都支持它,包括Internet Explorer,Google Chrome,Firefox,Safari和Opera。
Socket.IO是一个JavaScript库和Node.js模块,可让您简单快速地创建基于双向事件的实时通信应用程序。 它大大简化了使用WebSocket的过程。 我们将使用Socket.IO v1.0制作聊天室应用程序。
将Socket.IO添加到package.json
package.json
是一个文件,其中包含与项目相关的各种元数据,包括其依赖项。 npm可以使用此文件下载项目所需的模块。 看一下package.json的交互式解释及其包含的内容。
让我们将Socket.IO作为依赖项添加到项目中。 有两种方法可以做到这一点。
- 如果您已经按照教程系列进行操作,并且在Visual Studio安装程序中有一个项目,请右键单击该项目的npm部分,然后选择“安装新的npm软件包…”。
窗口打开后,搜索“ socket.io”,选择顶部结果,然后选中“添加到package.json”复选框。 点击“安装软件包”按钮。 这会将Socket.IO安装到您的项目中,并将其添加到package.json文件中。
package.json
{
"name": "NodeChatroom",
"version": "0.0.0",
"description": "NodeChatroom",
"main": "app.js",
"author": {
"name": "Rami Sayar",
"email": ""
},
"dependencies": {
"express": "3.4.4",
"jade": "*",
"socket.io": "^1.0.6",
"stylus": "*"
}
}
- 如果您使用的是OS X或Linux,则可以通过在项目文件夹的根目录中运行以下命令来实现与上述相同的操作。
npm install --save socket.io
将Socket.IO添加到app.js
下一步是将Socket.IO添加到app.js
。 您可以通过替换以下代码来实现……
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
…与:
var serve = http.createServer(app);
var io = require('socket.io')(serve);
serve.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
这将在名为serve
的变量中捕获HTTP服务器,并传递该HTTP服务器,以便Socket.IO
模块可以连接到该服务器。 最后一个代码块使用serve
变量并执行listen
功能,从而启动HTTP服务器。
记录用户加入和离开
理想情况下,我们要记录一个加入聊天室的用户。 以下代码通过挂接一个回调函数来实现这一点,该回调函数将通过WebSocket在每个单个connection
事件上执行到我们的HTTP服务器。 在回调函数中,我们调用console.log
记录用户已连接。 我们可以在调用serve.listen
之后添加此代码。
io.on('connection', function (socket) {
console.log('a user connected');
});
要在用户断开连接时执行相同的操作,我们必须为每个套接字disconnect
事件。 在上一个代码块的控制台日志之后,在内部添加以下代码。
socket.on('disconnect', function () {
console.log('user disconnected');
});
最后,代码将如下所示:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
广播在聊天频道上收到的消息
Socket.IO给我们提供了一个称为emit
事件的函数。
通过在回调中使用带有broadcast
标志的“ emit
,将在chat
通道上收到的任何消息广播到此套接字上的所有其他连接。
socket.on('chat', function (msg) {
socket.broadcast.emit('chat', msg);
});
最后,代码将如下所示:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
socket.on('chat', function (msg) {
socket.broadcast.emit('chat', msg);
});
});
将消息保存到NoSQL数据库
聊天室应将聊天消息保存到简单的数据存储中。 通常,有两种方法可以保存到Node中的数据库: 您可以使用特定于数据库的驱动程序,也可以使用ORM。 在本教程中,我将向您展示如何将消息保存到MongoDB。 当然,您可以使用任何其他喜欢的数据库,包括PostgreSQL或MySQL之类SQL数据库。
您应该确保已连接到MongoDB。 您可以使用第三方服务来托管您的MongoDB,例如MongoHQ或MongoLab。 查看本教程 ,了解如何使用Azure中的MongoLab加载项创建MongoDB 。 进入“创建应用程序”部分时,您可以停止阅读,只需确保将MONGOLAB_URI
保存在MONGOLAB_URI
可以轻松访问的位置。
一旦创建了MongoDB,并拥有数据库的MONGOLAB_URI
在已复制到剪贴板的“连接信息”下,您将要确保该应用程序可以使用URI。 在您的代码或源代码管理工具中的配置文件中添加敏感信息(例如此URI)不是最佳实践。 您可以将值添加到Azure Web应用程序的“配置”菜单中的“连接字符串”列表中(例如在所使用的教程中),也可以将其添加到“应用程序设置”列表中(名称为CUSTOMCONNSTR_MONGOLAB_URI
)。 在本地计算机上,可以将其添加到名称为CUSTOMCONNSTR_MONGOLAB_URI
和URI值的环境变量中。
下一步是在我们的项目中添加对MongoDB的支持。 您可以通过在package.json
的依赖项对象中添加以下行来实现。 确保将更改保存到文件中。
"mongodb": "^1.4.10",
在解决方案资源管理器中右键单击项目的npm部分,以显示右键单击上下文菜单。 从内容菜单中单击“安装缺少的软件包”以安装MongoDB软件包,以便将其用作模块。
我们希望导入该模块,以便能够使用app.js中的MongoDB客户端对象。 您可以在第一个require('')
函数调用之后添加以下代码行,例如第11行。
var mongo = require('mongodb').MongoClient;
我们想要使用CUSTOMCONNSTR_MONGOLAB_URI
环境变量中的URI连接到数据库。 连接后,我们要在套接字连接中插入收到的聊天消息。
mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
var collection = db.collection('chat messages');
collection.insert({ content: msg }, function(err, o) {
if (err) { console.warn(err.message); }
else { console.log("chat message inserted into db: " + msg); }
});
});
如您在上面的代码中看到的,我们使用process.env
对象获取环境变量值。 我们进入数据库中的一个集合,然后使用对象中的内容调用insert
函数。
现在,每条消息都被保存到我们的MongoDB数据库中。
发出收到的最后10条消息
当然,我们不希望用户一旦加入聊天室后就迷路,因此我们应确保将收到的最后10条消息发送到服务器,以便至少可以为他们提供一些上下文。 为此,我们需要连接MongoDB。 在这种情况下,我避免使用一个与数据库的连接来包装所有套接字代码,这样即使服务器失去了数据库连接,我仍然可以使服务器正常工作。
我们还将希望对查询进行排序并将查询限制为最后10条消息,我们将使用MongoDB generated _id
因为它包含时间戳记(尽管在更具伸缩性的情况下,您将希望在聊天消息中创建专用的时间戳记),并且将调用limit
函数将结果限制为仅10条消息。
我们将从MongoDB流式传输结果,以便我可以在它们到达时尽快将其发送到聊天室。
mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
var collection = db.collection('chat messages')
var stream = collection.find().sort({ _id : -1 }).limit(10).stream();
stream.on('data', function (chat) { socket.emit('chat', chat.content); });
});
上面的代码完成了前面几段中说明的工作。
部署到Azure
您可以按照过去的教程(如第2部分 )重新部署到Azure。
结论
总之,我们有一个聊天系统,能够将通过WebSockets接收的消息广播到所有其他连接的客户端。 系统将消息保存到数据库,并检索最后10条消息,以为加入聊天室的每个新用户提供上下文。
敬请关注第4部分!
第4部分-建立一个聊天室UI自举是在这里 。 通过关注我的twitter帐户,您可以了解有关本文和其他文章的最新信息 。
有关Azure上节点的更多学习
要对节点进行更深入的学习, 可以在Microsoft Virtual Academy上找到我的课程。
或一些类似节点主题的短格式视频:
本文是Microsoft的Web开发技术系列的一部分。 我们很高兴与您分享Project Spartan及其新的渲染引擎 。 获取免费的虚拟机或者在你的Mac,iOS设备,Android或Windows设备上远程测试modern.IE 。
翻译自: https://www.sitepoint.com/build-node-js-powered-chatroom-web-app-node-mongodb-socket/
自制chatroom