在现代 Web 应用程序中,实时性已经成为了重要的需求,特别是在在线聊天或协作应用中。基于 HTTP 的 WebSockets 协议无疑是最流行的实现方式之一,但是它可能并不适合所有的场景。在本文中,我们将探讨如何使用 Server-Sent Events(以下简称 SSE)和 React 构建一个简单但功能强大的实时聊天应用程序。
什么是 SSE?
Server-Sent Events 是一种基于 HTTP 的协议,用于在浏览器和服务器之间实现实时通信。与 WebSockets 不同,SSE 不需要建立长连接,而是通过标准的 HTTP 请求和响应机制。服务器端向客户端发送一条消息时,它会将此消息作为一个事件流发送给客户端,而客户端则可以使用 EventSource API 来接收和处理这个事件流消息。
SSE 支持以下特性:
- 支持浏览器与服务器之间的实时通信。
- 通过 HTTP(不需要握手)发送事件流消息。
- 支持重新连接,自动重连当连接中断时。
- 没有必要额外的 JavaScript 库或框架,原生的浏览器 API 就可以使用 SSE。
- 在不支持 WebSocket 的环境下也可以使用 SSE。
构建聊天应用的基本思路
我们将使用 SSE 来实现客户端和服务器端的实时通信,React 用于构建前端 UI。我们的聊天应用将基于以下的基本构想:
- 客户端连接到服务器,以接收来自其他聊天室成员的消息。
- 客户端在输入框中输入消息并将其发送到服务器。
- 服务器将接收到的消息广播给聊天室中的所有客户端。
以下是我们将聊天应用程序分为三个主要组件:
ChatApp
: 该组件是聊天应用的主要界面,并渲染用户列表(已连接的用户列表)和聊天消息。MessageList
: 该组件是展示聊天消息的组件,它接收一个消息列表并渲染每个消息。MessageForm
: 该组件允许用户向聊天室发送消息。
为聊天应用程序设置 SSE
我们将使用 Express 和 Node.js 来创建简单的服务器。在服务器上实现 SSE 是非常简单的。首先,我们需要设置一个 /stream
路由作为 SSE 的服务端点。
app.get('/stream', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); res.flushHeaders(); // SSE 服务端逻辑 });
在这里,我们设置了响应标头 Content-Type
为 text/event-stream
,使其成为 SSE,同时 Cache-Control
标头被设置为 no-cache
,以确保浏览器不会进行缓存。Connection
标头被设置为 keep-alive
,因为 SSE 的过程中需要维持打开的 HTTP 连接,直到客户端请求关闭它为止。
现在,我们可以编写 SSE 服务器代码来定期发送事件消息给客户端。
// javascriptcn.com 代码示例 function sendMessage(res, event, data) { res.write(`event: ${event}\n`); res.write(`data: ${JSON.stringify(data)}\n\n`); } setInterval(() => { const message = {/*...*/}; sendMessage(res, 'new_message', message); }, 5000);
在这里,我们使用 sendMessage
函数发送事件消息。在这个函数中,我们使用了 SSE 规范中的事件和数据字段来创建 SSE 事件消息。我们定期调用此函数以发送特定事件消息。
创建 React 组件
现在我们来编写 React 组件来实现 UI。我们可以创建一个 ChatApp
组件,它负责呈现聊天应用程序的整体 UI,并渲染 MessageList
和 MessageForm
。
// javascriptcn.com 代码示例 function ChatApp() { const [messages, setMessages] = useState([]); // SSE 客户端逻辑 const handleSendMessage = (message) => { // 向服务器发送消息的逻辑 }; return ( <div> <MessageList messages={messages} /> <MessageForm onSendMessage={handleSendMessage} /> </div> ); }
其中,useState
被用于维护消息列表 messages
。我们将在后面的章节中对此进行更新。
现在,我们需要捕获 SSE 事件流来接收从服务器发送的消息。为此,请创建一个 useSSE
Hook,它充当 SSE 客户端。
// javascriptcn.com 代码示例 function useSSE() { const [messages, setMessages] = useState([]); useEffect(() => { const source = new EventSource('/stream'); source.onerror = (err) => { console.error(err); source.close(); }; source.addEventListener('new_message', (ev) => { const data = JSON.parse(ev.data); setMessages((msgs) => [...msgs, data]); }); return () => { source.close(); }; }, []); return messages; }
在这里,我们使用 useEffect
和 EventSource
来设置 SSE 客户端。使用 useState
创建消息状态,然后我们建立 SSE 连接以接收 new_message
事件,并将每个新消息添加到状态中。
我们可以随时取消 SSE 连接,以避免内存泄漏。
最后,我们需要编写 MessageForm
组件,它负责接收用户消息并将它们发送到服务器。
// javascriptcn.com 代码示例 function MessageForm({ onSendMessage }) { const [message, setMessage] = useState(''); const handleSubmit = (e) => { e.preventDefault(); onSendMessage(message); setMessage(''); }; return ( <form onSubmit={handleSubmit}> <input type="text" value={message} onChange={(e) => setMessage(e.target.value)} /> <button type="submit">Send</button> </form> ); }
在这里,MessageForm
接收 onSendMessage
函数作为 prop。我们只需从 handleSubmit
回调函数中调用它并传递当前消息即可。
现在,我们已经准备好了,我们可以将所有部分组合在一起,并创建一个简单、实时的聊天应用程序。
示例代码
完整的代码可以访问:使用 React 和 Server-Sent Events 构建实时聊天应用
使用 Git 克隆或下载并解压此存储库后,先打开命令行,进入到 sse-react-chat-master
文件夹中,然后安装所有必须的 NPM 模块:
npm install
然后运行应用程序:
npm run start
最后在浏览器中打开 http://localhost:3000 即可体验实时聊天应用程序。
总结
在这篇文章中,你学习了如何使用 SSE 和 React 来构建一个实时聊天应用程序。通过所提供的示例代码、说明和许多实践的架构环节的领导,你已经可以启动并运行一个实时聊天应用程序了。这扩展了你的接触表面,包括 React 和 Server-Sent Events。在以后的学习中,它将为你提供强有力的工具,以创建可靠的实时 Web 应用程序。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654368d57d4982a6ebd282d4