簡體   English   中英

Socket.io - React:如何在 React 中檢索保存的 socket.io 數據(MongoDB)?

[英]Socket.io - React : How to retrieve saved socket.io data (MongoDB) in React?

在加入之前,我遵循了一些關於如何顯示聊天室中發送的消息的教程,但我不知道如何在 React 中顯示它們,並且我在服務器端有以下幾個問題。

客戶端,在構造函數中:

this.state = {
 msg: "",
 messages: []
};

客戶端,我有一個表單,單擊按鈕將通過此功能將消息發送到服務器:

sendMessage(e) {
 e.preventDefault();
 let msg = this.state.msg;
 this.socket.emit("sendMessage", msg);
 this.setState({ msg: "" });
}

服務器端,我有一個消息的貓鼬模式,名為 Message ,數據庫中的集合是消息。

const Message = new mongoose.Schema({
 sender: {
  type: "string"
 },
 message: {
  type: "string"
 }
});

var messages = [];

io.on("connection", (socket, user) => {
var user = socket.request.session.user;

Message.find({}).exec((err, messages) => {
 if (err) throw err;
 console.log(messages);
 io.emit("showingPastMessages", messages);
});

console.log(messages) 在 PowerShell 中顯示在 Mongo 中保存在 JavaScript 對象數組中的所有消息(條目)? [{id_ : 4qxxx, sender : 'user123', message : 'hello!'}, {id_ : 5exxx, sender : 'user456', message : 'hi!'}] 我想知道是否可以訪問僅發送者和消息屬性將其發送到客戶端? 類似於 messages.sender + messages.message 因為當我 console.log(messages.message) 它顯示未定義

這是服務器接收發送的消息然后將其保存在 Mongo 的地方。

socket.on("sendMessage", function(msg) {
var newMsg = new Message({ message: msg, sender: user });
 newMsg.save(function(err) {
   if (err) {
     console.log(err);
   } else {
     messages.push(newMsg);
     console.log(newMsg);
     console.log(messages);
   }
 });
});

console.log(newMsg) 顯示發送的最新消息,但 console.log(messages) 不顯示以前的消息,而只顯示最新的消息,為什么?

那么在 React 中,我應該在構造函數中,在 ComponentDidMount() 中有這樣的東西嗎? 如果它應該與 prevState

this.socket.on("showingPastMessages", function(messages){
 this.setState({ ...this.state.messages, messages})
});

你能給我一些建議嗎?

這是我的客戶端代碼來檢索數據:

class Chat extends Component {
 constructor(props) {
 super(props);

 this.state = {
  msg: "",
  messages: []
 };

 var socket = io('http://localhost:3000');
 this.socket.on("history", function(messages) {
  console.log(messages);
 });
}

這是一個好的開始。 我建議做的是讓這更受事件驅動。 為此,您需要在連接時將插座添加到房間。 有多少房間以及如何拆分房間將取決於您的應用程序,但我將演示基本思想。

首先,當套接字連接到您的服務器時,將該套接字添加到房間並立即發出您的聊天記錄。

io.on('connection', async (socket) => {
  socket.user = socket.request.session.user;

  socket.join('chat');

  try {
    const messages = await Message.find({});

    socket.emit('history', messages);
  } catch (err) {
    // Handle this error properly.
    console.error(err);
  }
});

然后,稍后,當您收到一條消息時,您需要保存該消息並將其發送到聊天室中的所有套接字。

socket.on("sendMessage", (msg, callback) => {
  const message = new Message({ message: msg, sender: socket.user });

  message.save(function(err) {
    if (err) {
      return callback(err);
    }

    io.to('chat').emit('message', message);
  });
});

最后,在客戶端,您需要監聽歷史事件。 當您收到它時,您需要清除您當前擁有的聊天記錄並將其替換為服務器告訴您的內容。 也許這看起來像

socket.on('history', (messages) => {
  this.setState({ messages });
});

您還需要偵聽此message事件,但使用此事件,您只會將消息附加到您的歷史記錄中。 這可能看起來像

socket.on('message', (message) => {
  this.setState({ messages: [ ...messages, message ] });
});

一個警告,如果當你告訴服務器一條新消息時,在你收到message事件之前不要將它添加到你的messages狀態數組中。 如果你這樣做,你會注意到雙重消息。 例如,這可能看起來像

onSendMessage(evnt) {
  evnt.preventDefault();

   socket.emit("sendMessage", msg);
   this.setState({ msg: "" });
}

注意:在收到來自 OP 的一些反饋后,我想添加一個關於將事件處理程序附加到套接字的位置(即所有socket.on )的部分。 我的建議是在io.on('connection')回調中在文件底部定義Message模式的文件中添加此代碼。 例如,

const Message = new mongoose.Schema({/*...*/});

io.on('connection', (socket) => {
  // Everything else I wrote above...

  socket.on('sendMessage', (msg, callback) => {
    // ...
  });
});

在客戶端,可能會在安裝聊天組件時注冊事件處理程序。 例如,

class ChatComponent extends React.Component {
  componentDidMount() {
    this.socket = io('https://your-server-or-localhost/');

    this.socket.on('history', (messages) => {
      // See above...
    });
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM