Laravel 应用程序与 socket.io 的设置问题

问题描述 投票:0回答:1

我尝试将 socket.io 与 Laravel 集成,但没有成功。我一直无法找到全面的文档来促进这种集成。我遵循了 Laracasts 的一些文档,但它似乎已经过时并且没有解决我的问题。任何人都可以提供有关将 socket.io 与 Laravel 正确集成的指导吗?我热切地等待您的回复。

我尝试过将socket.io与Laravel集成,但没有成功。

javascript php websocket socket.io laravel-10
1个回答
0
投票

您找不到在 Laravel 中使用 Socket.IO 的像样指南的原因是,将两者一起使用并不常见,并且还有许多其他更好的替代方案可与 Laravel 一起使用,例如 Pusher 或 Reverb。

但是,由于我之前已经去过那里,我将向您简要解释如何将 Socket.IO 和 Laravel 连接在一起,但请记住,这只是一个基本示例,不应该在无需修改的现实生活项目。

我们这里有两台服务器:

  • Laravel Server:托管您的 Laravel 应用程序
  • Socket.IO 服务器:提供套接字

首先,你需要安装并运行 Redis,Redis 在这里很重要,因为它用于在 Socket.IO 和 Laravel 之间传递消息(也称为

broker
)。

在单独的目录中创建一个单独的 Node.js 项目,并在其中安装以下依赖项:

  • ioredis:允许 Node.js 与正在运行的 Redis 实例交互
  • socket.io:允许您创建Socket.IO服务器
  • express:允许您创建 HTTP 服务器。这在我们的例子中很有用,因为我们将使用这个包通过 HTTP 公开套接字服务器。

您可以通过运行以下命令来安装所有这些依赖项:

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-

发生的事情是这样的:

  • Laravel 使用 Redis 广播器广播消息
  • 广播过程涉及向 Redis 发出包含消息数据的
    PUBLISH
    命令
  • Socket.IO 服务器正在观察 Redis 的任何
    PUBLISH
    命令,因此当消息到来时,会触发
    pmessage
    事件。
  • 在对
    pmessage
    事件的回调中,Socket.IO 向指定通道上的所有订阅者广播消息。
© www.soinside.com 2019 - 2024. All rights reserved.