首頁 > web前端 > js教程 > 主體

React:確保持久性資料和無縫會話

WBOY
發布: 2023-09-01 21:49:05
原創
781 人瀏覽過

React:確保持久性資料和無縫會話

擁有「記住我」功能是一個非常有用的功能,並且使用 React 和 Express 實作相對容易。繼續我們設定 WebRTC 聊天應用程式的上一部分,我們現在將添加 Mongo 支援的持久性會話和資料庫支援的線上使用者清單以進行良好的衡量。

會話?

如果您以前沒有使用過會話,簡而言之,它們與 cookie 非常相似,因為會話使您能夠即時追蹤應用程式的活躍用戶。會話實際上是透過 會話 cookie 工作的,該 cookie 在您的應用程式的請求/回應標頭中發送。

因此 cookie 和會話本質上是交織在一起的。如果我們已經有了cookie,為什麼還需要會話呢?會話還為您提供了定義應用程式的伺服器部分所使用的後端儲存的能力。這意味著只要您的應用程式需要該信息,就可以從資料庫中檢索該資訊。

因此,在我們的聊天應用程式的現實範例中,我們現在可以儲存使用者的使用者名稱 - 如果我們稍微重新配置我們的應用程序,也將整個聊天歷史記錄插入到資料庫中進行記錄。

在下一個範例中,我們將使用 Mongo 資料庫進行持久後端儲存。這是可用於會話儲存的幾個選項之一,對於具有多個 Web 伺服器的大規模生產設置,我強烈推薦的另一個選項是 memcache。

文檔儲存

Mongo 是一個 NoSQL 文件儲存引擎,而不是像流行的 MySQL 那樣的關聯式資料儲存。如果您以前使用過 MySQL 或類似資料庫並且需要快速了解 Mongo,那麼 NoSQL 真的很容易上手——這不會花費您很長時間。您應該了解的最大差異如下:

  • 顧名思義,NoSQL 不使用 SQL 來執行查詢。相反,資料是透過方法呼叫來抽象化的;例如 db.collectionName.find() 將會是 SELECT * FROM table
  • 術語不同:在 MySQL 中,我們有表格、行和列,而在 Mongo 中,有集合、文件和鍵。
  • 資料是結構化的,與 JSON 物件相同。

如果您還沒有 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-sessionconnect-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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!