我尝试将 socket.io 与 Laravel 集成,但没有成功。我一直无法找到全面的文档来促进这种集成。我遵循了 Laracasts 的一些文档,但它似乎已经过时并且没有解决我的问题。任何人都可以提供有关将 socket.io 与 Laravel 正确集成的指导吗?我热切地等待您的回复。
我尝试过将socket.io与Laravel集成,但没有成功。
您找不到在 Laravel 中使用 Socket.IO 的像样指南的原因是,将两者一起使用并不常见,并且还有许多其他更好的替代方案可与 Laravel 一起使用,例如 Pusher 或 Reverb。
但是,由于我之前已经去过那里,我将向您简要解释如何将 Socket.IO 和 Laravel 连接在一起,但请记住,这只是一个基本示例,不应该在无需修改的现实生活项目。
我们这里有两台服务器:
首先,你需要安装并运行 Redis,Redis 在这里很重要,因为它用于在 Socket.IO 和 Laravel 之间传递消息(也称为
broker
)。
在单独的目录中创建一个单独的 Node.js 项目,并在其中安装以下依赖项:
您可以通过运行以下命令来安装所有这些依赖项:
npm install ioredis socket.io express
现在我们需要创建 Socket.IO 服务器并公开它,这是一个带注释的实现:
const express = require("express"); // include express
const { Server } = require("socket.io"); // include the Server class from Socket.IO
const { Redis } = require("ioredis"); // include the Redis class
// instantiate an express app
const app = express();
const http = require("http");
// create an HTTP server
const server = http.createServer(app);
// create a Socket.IO server that uses the previously declared HTTP server
// and allow it to be accessible from any origin, and restrict it so that it
// only accepts GET and POST requests
const io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
}
});
// instantiate an object to interact with Redis
const redis = new Redis();
// subscribe to all PUBLISH events done in Redis
redis.psubscribe("*");
// the on() method is used to listen to different events from Redis
// whenever a new message is published into Redis using the PUBLISH command
// this is what the "message" event means
// a "message" event is triggered everytime Laravel dispatches a broadcastable event, we'll come to that later
redis.on("pmessage", function (pattern, channel, message) {
// just log the message
console.log('Message Received: ' + message);
console.log('Channel: ' + channel);
// parse the message
message = JSON.parse(message);
// broadcast the message to the subscribed clients
server.emit(channel + ':' + message.event, message.data);
});
// the "connection" event is triggered every time there's a new client that
// subscribed to the Socket.IO server
io.on("connection", function (socket) {
console.log("New connection")
// the "data" event is triggered every time the socket receives incoming data
socket.on("data", function (data) {
console.log("Received data: " + data);
});
});
// expose the Socket.IO server through HTTP port 6001
server.listen(6001);
好吧,让我们看看 Laravel 这边会发生什么。首先,我们需要将广播驱动设置为Redis。为此,请打开
.env
并设置 BROADCAST_DRIVER
,如下所示:
BROADCAST_DRIVER=redis
这就是全部,您不必更改事件类中的任何其他内容。只需确保您的事件类实现
Illuminate\Contracts\Broadcasting\ShouldBroadcast
接口即可。
假设我们有一个名为
OrderUpdated
的事件,该事件将在名为 orders
的公共频道上广播。在这种情况下,在您的刀片模板中,您将如何收听此事件:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.min.js"></script>
<script>
// don't forget to replace 127.0.0.1 with your own server address, if you're not on localhost
const socket = io("http://127.0.0.1:6001");
// this event fires when the client connects successfully to the socket server
socket.on("connect", function() {
console.log("connected to socket");
});
// listen to the OrderUpdated event on the orders channel
socket.on("orders:OrderUpdated", function(e){
console.log(e)
});
</script>
请注意,如果您在私人频道上广播活动,则必须在刀片代码中为频道名称添加前缀
private-
。例如:
socket.on("private-orders:OrderUpdated");
在线状态频道也是如此,只需添加前缀
presence-
。
发生的事情是这样的:
PUBLISH
命令PUBLISH
命令,因此当消息到来时,会触发 pmessage
事件。pmessage
事件的回调中,Socket.IO 向指定通道上的所有订阅者广播消息。