我有一个 nuxtjs 前端应用程序和一个在不同服务器上运行的 php 后端。 我正在设置实时聊天。一旦发送了新消息(即“嘿,我收到了房间“foo”的新消息,获取它并通知其他收件人”),后端就会发布到 Redis 服务器。所以我应该订阅特定的redis频道,然后通知其他人。 我的想法更多的是我应该如何处理这个问题。 我是否需要像 socket.io 这样的东西来与我的 redis 服务器通信? 我应该只使用 redis.createClient() 来启动一个 redis 实例,然后(动态)订阅我已经进入或添加的每个新房间吗?
我试图为这个主题找到更好的实现,我确实可以使用它,我的问题是,在安装之前我收到一个错误:
Firefox 无法与 http://localhost:3000/api/redis?channel=ads_channel 处的服务器建立连接。
但无论如何它工作得很好。
首先:安装npm i ioredis。
第二:在 nuxt/server/api 文件夹中创建端点。
服务器/api/redis.ts
import Redis from "ioredis";
const redisClient = new Redis(6379);
redisClient.on("error", (err) => console.error("Redis Client Error",err));
export default defineEventHandler((e) => {
e.node.res.writeHead(200, {
"Cache-Control": "no-cache",
Connection: "keep-alive",
"Content-Type": "text/event-stream",
});
const { channel } = getQuery(e);
redisClient.subscribe(channel, (err, count) => {
if (err) {
e.node.res.end(JSON.stringify({ error: err.message }));
return;
}
redisClient.on("message", (channel, message) => {
e.node.res.write(`data: ${message}\n\n`);
});
// e.node.res.setHeader("Content-Type", "text/event-stream");
// e.node.res.setHeader("Cache-Control", "no-cache");
// e.node.res.setHeader("Connection", "keep-alive");
});
return true;
});
第三:现在在您的组件或页面中添加以下内容:
onMounted(() => {
const connectEventSource = () => {
const eventSource = new EventSource(`/api/redis?channel=your_channel_name`);
eventSource.onmessage = (event) => {
let parsed = JSON.parse(event.data);
console.log(parsed);
};
eventSource.onerror = (error) => {
console.error("EventSource failed:", error);
eventSource.close();
setTimeout(connectEventSource, 5000); // Retry connection after 5 seconds
};
};
setTimeout(connectEventSource, 1000);
});