【发布时间】:2020-10-18 14:54:48
【问题描述】:
我目前正在学习 webDevSimplified 的教程
youtube:https://www.youtube.com/watch?v=tBr-PybP_9c
github 仓库:https://github.com/WebDevSimplified/Whatsapp-Clone
我已经将我的代码与 repo 进行了无数次比较,还阅读了 socket.io 的文档,但无济于事。
已经有一些线程存在类似的问题,但许多线程没有得到答复,或者只是设置完全不同。
我在项目中使用了 yarn 包管理器,而不是教程中所示的 npm,但我怀疑这是罪魁祸首。我已经安装了所有必需的依赖项。
让我们从 server.js
开始const io = require('socket.io')(5000) // I changed it to 3000 but just got a different Error(see title)
io.on('connection', socket => {
const id = socket.handshake.query.id
socket.join(id)
socket.on('send-message', ({ recipients, text }) => {
recipients.forEach(recipient => {
const newRecipients = recipients.filter(r => r !== recipient)
newRecipients.push(id)
socket.broadcast.to(recipient).emit('receive-message', {
recipients: newRecipients, sender: id, text
})
})
})
})
在这个应用程序中,我们使用useContext 为我们的组件提供套接字。
这里是 socketProvider.js
import React, { useContext, useEffect, useState } from "react";
import io from "socket.io-client";
const SocketContext = React.createContext();
export function useSocket() {
return useContext(SocketContext);
}
export function SocketProvider({ id, children }) {
const [socket, setSocket] = useState();
//console.log(socket)
useEffect(() => {
const newSocket = io("http://localhost:5000", { query: { id } });// I changed the host here as well to 3000 but I either get a POST or a GET error respectively
setSocket(newSocket);
return () => newSocket.close();
}, [id]);
return (
<SocketContext.Provider value={socket}>{children}</SocketContext.Provider>
);
}
然后嵌套在另一个 contextProvider aka ConversationsProvider.js
import React, { useContext, useState, useEffect, useCallback } from "react";
import useLocalStorage from "../hooks/useLocalStorage";
import { useContacts } from "./ContactsProvider";
import { useSocket } from "./SocketProvider";
const ConversationsContext = React.createContext();
export function useConversations() {
return useContext(ConversationsContext);
}
export function ConversationsProvider({ id, children }) {
const [conversations, setConversations] = useLocalStorage("conversations",[]);
const [selectedConversationIndex, setSelectedConversationIndex] = useState(0);
const { contacts } = useContacts();
const socket = useSocket();
function createConversation(recipients) {
setConversations((prevConversations) => {
return [...prevConversations, { recipients, messages: [] }];
});
}
const addMessageToConversation = useCallback(({ recipients, text, sender }) => {
setConversations((prevConversations) => {
let madeChange = false;
const newMessage = { sender, text };
const newConversations = prevConversations.map((conversation) => {
if (arrayEquality(conversation.recipients, recipients)) {
madeChange = true;
return {
...conversation,
messages: [...conversation.messages, newMessage],
};
}
return conversation;
});
if (madeChange) {
return newConversations;
} else {
return [...prevConversations, { recipients, messages: [newMessage] }];
}
});
}, [setConversations])
useEffect(() => {
if(socket == null) return
socket.on('receive-message', addMessageToConversation)
return () => socket.off('receive-message')
},[socket, addMessageToConversation])
function sendMessage(recipients, text) {
socket.emit('send-message', { recipients, text })
addMessageToConversation({ recipients, text, sender: id });
}
const formattedConversations = conversations.map((conversation, index) => {
const recipients = conversation.recipients.map((recipient) => {
const contact = contacts.find((contact) => {
return contact.id === recipient;
});
const name = (contact && contact.name) || recipient;
return { id: recipient, name };
});
const messages = conversation.messages.map(message => {
const contact = contacts.find((contact) => {
return contact.id === message.sender;
})
const name = (contact && contact.name) || message.sender;
const fromMe = id === message.sender
return { ...message, senderName: name, fromMe }
})
const selected = index === selectedConversationIndex;
return { ...conversation, messages, recipients, selected };
});
const value = {
conversations: formattedConversations,
selectedConversation: formattedConversations[selectedConversationIndex],
sendMessage,
selectConversationIndex: setSelectedConversationIndex,
createConversation,
};
return (
<ConversationsContext.Provider value={value}>
{children}
</ConversationsContext.Provider>
);
}
function arrayEquality(a, b) {
if (a.length !== b.length) return false;
a.sort();
b.sort();
return a.every((element, index) => {
return element === b[index];
});
}
我之前没有使用 websocket.API / socket.io 的经验,我还没有完全理解工作流程。我希望有人能看到我到目前为止没有看到/注意到的错误。
我认为这种反应设置与常规设置略有不同,因为我在网上找不到任何可能有助于解决我的问题的类似设置。
如果您认为它可能相关,请查看上面的主存储库。我的本地文件夹结构和代码都是一样的。
我将尝试另一个堆栈,看看是否可以使用 node.js 运行它,或者同时尝试文档中的示例。
【问题讨论】:
标签: reactjs socket.io chat use-context