拥有“记住我”功能是一个非常有用的功能,并且使用 React 和 Express 实现相对容易。继续我们设置 WebRTC 聊天应用程序的上一部分,我们现在将添加 Mongo 支持的持久会话和数据库支持的在线用户列表以进行良好的衡量。
如果您以前没有使用过会话,简而言之,它们与 cookie 非常相似,因为会话使您能够实时跟踪应用程序的活跃用户。会话实际上是通过 会话 cookie
工作的,该 cookie 在您的应用程序的请求/响应标头中发送。
因此 cookie 和会话本质上是交织在一起的。如果我们已经有了cookie,为什么还需要会话呢?会话还为您提供了定义应用程序的服务器部分使用的后端存储的能力。这意味着只要您的应用需要该信息,就可以从数据库中检索该信息。
因此,在我们的聊天应用程序的现实示例中,我们现在可以存储用户的用户名 - 如果我们稍微重新配置我们的应用程序,还将整个聊天历史记录插入到数据库中进行记录。
在下一个示例中,我们将使用 Mongo 数据库进行持久后端存储。这是可用于会话存储的几个选项之一,对于具有多个 Web 服务器的大规模生产设置,我强烈推荐的另一个选项是 memcache。
Mongo 是一个 NoSQL 文档存储引擎,而不是像流行的 MySQL 那样的关系数据存储。如果您以前使用过 MySQL 或类似数据库并且需要快速了解 Mongo,那么 NoSQL 真的很容易上手——这不会花费您很长时间。您应该了解的最大区别如下:
db.collectionName.find()
将是 SELECT * FROM table
。如果您还没有 Mongo,请通过包管理器安装它。例如,在基于 Linux 的发行版中:
$ sudo apt-get install mongodb
安装 Mongo 后,我们可以使用 npm 提供的 mongoose
模块轻松地将 Mongo 支持添加到我们的聊天应用程序中。使用以下命令安装 mongoose
:
$ npm install mongoose --save
现在让我们向我们的应用程序添加一些 Mongo。启动代码编辑器,然后打开 app.js
并将脚本的顶部设置如下。
//Configure our Services var PeerServer = require('peer').PeerServer, express = require('express'), mongoose = require('mongoose'), assert = require('assert'), events = require('./src/events.js'), app = express(), port = process.env.PORT || 3001; //Connect to the database mongoose.connect('mongodb://localhost:27017/chat'); var db = mongoose.connection; mongoose.set('debug', true); db.on('error', console.error.bind(console, '# Mongo DB: connection error:'));
我们将 mongoose
包含在 require('mongoose')
中,然后通过 mongoose.connect('mongodb:/ /本地主机:27017/chat');
。
/chat
定义我们要连接的数据库的名称。
接下来,出于开发目的,我建议我们将调试设置为打开。
mongoose.set('debug', true);
最后我们为任何错误事件添加一个处理程序:
db.on('error', console.error.bind(console, '# Mongo DB: connection error:'));
接下来,您可以使用以下代码添加对连接的检查:
db.once('open', function (callback) { console.log("# Mongo DB: Connected to server"); }
mongoose
的使用方式是,一旦 db
实例收到 open
事件,我们就会进入执行我们的 mongo 连接。因此,我们需要将现有代码包装到这个新的 mongo 连接中才能使用它。
下面是完整的代码清单,其中添加了 mongoose,并在用户上线和离线时插入行和删除行。
//Configure our Services var PeerServer = require('peer').PeerServer, express = require('express'), mongoose = require('mongoose'), assert = require('assert'), events = require('./src/events.js'), app = express(), port = process.env.PORT || 3001; //Tell express to use the 'src' directory app.use(express.static(__dirname + '/src')); //Connect to the database mongoose.connect('mongodb://localhost:27017/chat'); var db = mongoose.connection; mongoose.set('debug', true); db.on('error', console.error.bind(console, '# Mongo DB: connection error:')); db.once('open', function (callback) { console.log("# Mongo DB: Connected to server"); //Setup our User Schema var usersSchema = mongoose.Schema({username: String}); var User = mongoose.model('User', usersSchema); //Configure the http server and PeerJS Server var expressServer = app.listen(port); var io = require('socket.io').listen(expressServer); var peer = new PeerServer({ port: 9000, path: '/chat' }); //Print some console output console.log('#### -- Server Running -- ####'); console.log('# Express: Listening on port', port); peer.on('connection', function (id) { io.emit(events.CONNECT, id); console.log('# Connected: ', id); //Store Peer in database var user = new User({ username: id }); user.save(function (err, user) { if (err) return console.error(err); console.log('# User '+ id + ' saved to database'); }); }); peer.on('disconnect', function (id) { io.emit(events.DISCONNECT, id); console.log('# Disconnected: ', id); //Remove Peer from database User.remove({username: id}, function(err){ if(err) return console.error(err)}); }); });
要查看此效果,让我们启动聊天应用程序。只需运行 npm start
即可启动。
现在在浏览器中正常连接到聊天(默认为 http://localhost:3001)。
连接到聊天后,在新的终端窗口中打开 mongo chat
进入 mongo cli。
$ mongo chat MongoDB shell version: 2.0.6 connecting to: chat > db.users.find() { "username" : "CameronLovesPigs", "_id" : ObjectId("5636e9d7bd4533d610040730"), "__v" : 0 }
这里您的 mongo
中存储了文档记录,现在您可以随时通过在 mongo 提示符下运行 db.users.count 来检查有多少用户在线()
。
> db.users.count() 3
因为我们使用 Express 来构建我们的应用程序,所以这部分非常简单,只需要安装 npm
中的几个模块即可开始。
从 npm 获取 express-session
和 connect-mongo
包:
$ npm install express-session connect-mongo cookie-parser --save
现在将它们包含在 app.js
的顶部:
var PeerServer = require('peer').PeerServer, cookieParser = require('cookie-parser'), express = require('express'), session = require('express-session'), mongoose = require('mongoose'), MongoStore = require('connect-mongo')(session), //...
设置 mongoose.connect
后,您可以使用 Express 配置会话。将您的代码更改为以下内容;您可以指定自己的 secret
字符串。
//Connect to the database mongoose.connect('mongodb://localhost:27017/chat'); var db = mongoose.connection; mongoose.set('debug', true); db.on('error', console.error.bind(console, '# Mongo DB: connection error:')); app.use(cookieParser()); app.use(session({ secret: 'supersecretstring12345!', saveUninitialized: true, resave: true, store: new MongoStore({ mongooseConnection: db }) }))
这里需要注意的一个关键设置是最后一个 app.use
中的 saveUninitialized: true
。这将确保保存会话。
我们使用 store
属性指定位置,该属性设置为 MongoStore
实例,通过 mongooseConnection
和我们的 db
对象。
为了存储到会话中,我们需要使用express来处理请求,因为我们需要访问请求值,例如:
//Start persistent session for user app.use(function(req, res, next) { req.session.username = id; req.session.save();
这将使用用户输入的值创建 req.session.username
变量并保存以供稍后使用。
接下来,我们可以使用客户端代码检查此值,并在用户刷新时自动登录,这样他们就永远不会退出聊天并自动以其选择的用户名登录。
还值得注意的是,因为我们有数据库支持的会话,所以如果开发人员更改应用程序和后端重新加载,登录到其客户端的用户将保持登录状态,因为会话存储是现在执着。这是一个很棒的功能,可以让您的用户在开发过程中或在与不稳定的客户端断开连接时始终保持登录状态。
现在我们已经设置了会话 cookie 部分,接下来让我们将持久登录添加到我们的前端代码中。
到目前为止,我们只是使用了 Express 为 SPA 应用程序提供的默认路由,并没有为 Express 定义任何路由处理。正如我之前提到的,要访问会话,您将需要 Express 的请求/响应变量。
首先,我们需要一个路由,以便我们可以访问 Express 提供的 request
对象并显示它以进行调试。在 /app.js
中的 Express 配置内,在会话设置之后,在文件顶部附近添加以下内容:
app.use(session({ secret: 'supersecretstring12345!', saveUninitialized: true, resave: true, store: new MongoStore({ mongooseConnection: db }) })) app.get('/', function (req, res) { res.sendFile(__dirname +'/src/index.html'); if(req.session.username == undefined){ console.log("# Username not set in session yet"); } else { console.log("# Username from session: "+ req.session.username); } });
现在我们有一些基本的日志记录来查看我们的会话值发生了什么。为了设置它,我们需要像这样配置 getter 和 setter 路由:
//Save the username when the user posts the set username form app.post('/username', function(req, res){ console.log("# Username set to "+ req.body.username); req.session.username = req.body.username; req.session.save(); console.log("# Session value set "+ req.session.username); res.end(); }); //Return the session value when the client checks app.get('/username', function(req,res){ console.log("# Client Username check "+ req.session.username); res.json({username: req.session.username}) });
这两条路由将用作用户名会话变量的获取和设置。现在,通过一些基本的 JavaScript,我们可以为我们的应用程序实现自动登录。打开src/App.js
,修改如下:
/* global EventEmitter, events, io, Peer */ /** @jsx React.DOM */ $(function () { 'use strict'; // Check for session value $(document).ready(function(){ $.ajax({ url: '/username' }).done(function (data) { console.log("data loaded: " + data.username); if(data.username) initChat($('#container')[0], data.username); }); }); // Set the session $('#connect-btn').click(function(){ var data = JSON.stringify({username: $('#username-input').val()}); $.ajax({ url: '/username', method: "POST", data: data, contentType: 'application/json', dataType: 'json' }); }); // Initialize the chat $('#connect-btn').click(function () { initChat($('#container')[0], $('#username-input').val()); }); function initChat(container, username) { var proxy = new ChatServer(); React.renderComponent(, container); } window.onbeforeunload = function () { return 'Are you sure you want to leave the chat?'; }; });
使用 jQuery 的 $.ajax
工具,我们创建一个请求,以在 文档
可用时检查会话变量的值。如果设置了,我们就会使用存储的值初始化我们的 React 组件,从而为我们的用户提供自动登录功能。
使用 npm start
再次启动聊天,并在浏览器中查看会话是否正常工作。
现在您已经看到将 Mongoose 与 Express 结合使用并设置 Express 会话是多么容易。使用 React 作为链接到数据库支持元素的视图控制器来进一步开发应用程序将创建一些重要的应用程序。
如果您想进一步了解 React 并了解组件如何在 React 框架内部相互通信,官方文档中的这份指南非常有用。
以上是React:确保持久数据和无缝会话的详细内容。更多信息请关注PHP中文网其他相关文章!