by Adnan Sabanovic
由Adnan Sabanovic
如何在Socket.IO中使用Laravel (How to use Laravel with Socket.IO)
Websockets are cool. They are really helpful if you want to show real-time activities from your users (or perhaps some queue jobs).
Websocket很酷。 如果您想显示用户的实时活动(或一些队列作业),它们将非常有用。
Now, if you are afraid of the word “Websockets”, don’t be. I will lay down the instructions on how you can use it and will be around to answer your questions if you need to.
现在,如果您担心“ Websockets ”这个词,那就不要了。 我将说明如何使用它,并在需要时回答您的问题。
I had this challenge where I needed it to show a list of people who are currently viewing a specific URL in Laravel. So I started thinking. Part of me wanted to do a quick hack (luckily that’s not the strongest side of mine). Whilst the other wanted to build something cool, reusable and long-lasting.
我遇到了这个挑战,需要它来显示当前正在Laravel中查看特定URL的人员列表 。 于是我开始思考。 我的一部分希望快速进行破解(幸运的是,这并不是我最强的一面)。 另一个则想构建一些很酷,可重复使用且持久的东西。
“为什么不只使用Pusher?” (“Why don’t you just use Pusher?”)
Here is the thing.
这是东西。
Laravel comes with Pusher enabled. Even though Pusher seems like a quick “Plug and play” solution (which it is), it comes with limitations. Check out https://pusher.com/pricing
Laravel启用了Pusher。 尽管Pusher似乎是一种快速的“ 即插即用 ”解决方案(确实如此),但它也有局限性。 查看https://pusher.com/pricing
And most of the tutorials trick you with their title of implementing Websockets when in reality they just want to give you Pusher. (And my favorite part is when they say that you can easily switch to socket.io)
而且大多数教程都以实现Websocket的标题来欺骗您,而实际上它们只是想给您Pusher。 (我最喜欢的部分是当他们说您可以轻松切换到socket.io时)
“我们希望拥有无限数量的连接” (“We want to have an unlimited number of connections”)
We don’t want to worry about limitations.
我们不想担心局限性。
Let’s start.
开始吧。
I am using vagrant / homestead.
我正在使用无业游民/宅基地。
For this, we will need to read about Event Broadcasting.
为此,我们将需要阅读有关事件广播 。
Things to note here (so I don’ t have to repeat things):
这里需要注意的事情(所以我不必重复):
1. ShouldBroadcast Interface for Events
1.事件的ShouldBroadcast接口
2. Enabling Broadcast routes and using routes/channels.php to authenticate users
2.启用广播路由并使用route / channels.php对用户进行身份验证
3. Public Channel — Everyone can listen
3.公共频道-每个人都可以收听
4. Private Channel — You need to authorize users before they can join a channel
4.专用频道-您需要先授权用户才能加入频道
5. Presence Channel — Like Private but you can pass a lot of additional metadata on that channel and get a list of people who have joined the channel.broadcastOn() Event method
5. Presence Channel —与Private一样,但是您可以在该频道上传递很多其他元数据,并获得加入channel.broadcastOn()事件方法的人员的列表。
建立活动 (Create Your Event)
php artisan make:event MessagePushed
You can even follow the specific example in the Event Broadcasting documentation. (Which we should really).
您甚至可以按照事件广播文档中的特定示例进行操作。 (我们应该这样)。
安装Redis (Install Redis)
Before this, I actually had queues setup with Supervisor/Redis/Horizon. Horizon is great and you can find information about that in here https://laravel.com/docs/5.6/horizon
在此之前,我实际上已经通过Supervisor / Redis / Horizon设置了队列。 Horizon很棒,您可以在这里https://laravel.com/docs/5.6/horizon中找到有关它的信息
Once you have your queues working, that MessagePushed event will need to use queues.
一旦您的队列开始工作,该MessagePushed事件将需要使用队列。
Note: For all of this to work, make sure you edit your .env file:
注意 :为了使所有这些正常工作,请确保您编辑.env文件:
BROADCAST_DRIVER=redis
QUEUE_DRIVER=redis
(this is from the horizon setup actually, but we will need that for later)
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
安装Laravel Echo Server (Install Laravel Echo Server)
So this part is actually where we install socket.io server that is bundled inside laravel-echo-server. You can find about it here: https://github.com/tlaverdure/laravel-echo-server
因此,这部分实际上是我们在laravel-echo-server中捆绑安装的socket.io服务器的安装位置。 您可以在这里找到它: https : //github.com/tlaverdure/laravel-echo-server
Note: Check the requirements at the top!
注意 :检查顶部的要求!
Run the following (as stated in the document)
运行以下命令(如文档中所述)
npm install -g laravel-echo-server
And then run the init in order to get your laravel-echo-server.json file generated in the app root (which we will need to configure).
然后运行init以便在应用程序根目录(我们将需要配置)中生成您的laravel-echo-server.json文件。
laravel-echo-server init
Once you have generated your laravel-echo-server.json file, it should look like this.
生成laravel-echo-server.json文件后,它应如下所示。
{
"authHost": "http://local-website.app",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "my-app-id",
"key": "my-key-generated-with-init-command"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
},
"port": "6379",
"host": "127.0.0.1"
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": ""
}
Note: If you want to push this to your public server, make sure to add laravel-echo-server.json to your .gitignore. Generate this file on the server, otherwise you will need to change your authHost all the time.
注意 :如果要将其推送到公共服务器,请确保将laravel-echo-server.json添加到您的.gitignore中。 摹 enerate服务器上的文件,否则就需要改变你的AUTHHOST所有的时间。
Run your Laravel Echo Server
运行您的Laravel Echo Server
You have to run it in order to start websockets.
您必须运行它才能启动websocket。
laravel-echo-server start
(inside your root — where your laravel-echo-server.json is placed)
(在您的根内部-放置laravel-echo-server.json的位置)
It should start successfully. (Now we will want to add this to supervisor on your server, so it is started automatically and restarted in case it crashes)
它应该成功启动。 (现在,我们将其添加到您服务器上的主管中,因此它会自动启动并在崩溃时重新启动)
Inside your /etc/supervisor/conf.d/laravel-echo.conf (just create this file inside your conf.d folder) place the following:
在/etc/supervisor/conf.d/laravel-echo.conf内部(只需在conf.d文件夹中创建此文件),放置以下内容:
[program:laravel-echo]
directory=/var/www/my-website-folder
process_name=%(program_name)s_%(process_num)02d
command=laravel-echo-server start
autostart=true
autorestart=true
user=your-linux-user
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/my-website-folder/storage/logs/echo.log
Once you position in your Laravel root, you can run
将您的Laravel根目录定位后,即可运行
pwd
to get the path for your ‘directory’ above and ‘stdout_logfile’ prefix.
获取上方“目录”和“ stdout_logfile”前缀的路径。
Your user will be your Linux user (vagrant or Ubuntu or some other)
您的用户将是您的Linux用户(无业,Ubuntu或其他)
Save the file and go out. If you used vim laravel-echo.conf then when inside, press I (like Istanbul) on your keyboard to edit a file with VIM and then type ESC following :wq! To close the file and save it.
保存文件然后出去。 如果您使用vim laravel-echo.conf,则在内部时,按键盘上的I(例如Istanbul)以使用VIM编辑文件,然后在:wq!之后键入ESC! 关闭文件并保存。
Next, we need to run the following commands:
接下来,我们需要运行以下命令:
sudo supervisorctl stop all sudo supervisorctl reread
sudo supervisorctl reload
After that check to see if laravel echo is running
之后,检查laravel echo是否正在运行
sudo supervisorctl status
安装Laravel Echo和Socket IO客户端 (Install Laravel Echo and Socket IO client)
npm install --save laravel-echo
npm install --save socket.io-client
And then in your bootstrap.js (I am using Vue js) register your Echo
然后在您的bootstrap.js(我正在使用Vue js)中注册您的Echo
import Echo from "laravel-echo"window.io = require('socket.io-client');
// Have this in case you stop running your laravel echo server
if (typeof io !== 'undefined') { window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001', });}
Now check again how to listen for your events on specific channels.
现在,再次检查如何收听特定频道上的事件。
Following the documentation on Laravel Broadcasting we shared above, if you set your broadcastOn() method to return a new PresenceChannel (I will explain the particular case I did, but feel free to ask questions in case you need something else implemented. I find this to be of higher complexity than simply using a public channel, so we can scale down with no problems) then we want to listen for that channel on Javascript side (frontend).
根据上面我们共享的Laravel Broadcasting的文档,如果您将broadcastOn()方法设置为返回新的PresenceChannel (我将解释我的特殊情况,但是如果您需要其他实现,请随时提问。我发现了而不是简单地使用公共渠道来实现更高的复杂度,因此我们可以毫无问题地进行缩减),然后我们希望在Javascript方面(前端)监听该渠道。
Here is a concrete example:
这是一个具体的例子:
- I pushed an event onto a presence channel (I was dealing with surveys) 我将一个事件推送到一个在线渠道(我正在处理调查)
public function broadcastOn()
{
return new PresenceChannel('survey.' . $this->survey->id);
}
2. After you push the event, it will go through channels.php. In there we want to create an authorization for this user. (Remember to return an array for presence channel authorization and not a Boolean.)
2.推送事件后,它将通过channels.php。 在这里,我们要为此用户创建一个授权。 (请记住,返回一个用于状态通道授权的数组,而不是布尔值。)
Broadcast::channel('survey.{survey_id}', function ($user, $survey_id) {
return [
'id' => $user->id,
'image' => $user->image(),
'full_name' => $user->full_name
];
});
3. Then in my VueJs component that loads on the page I want to monitor I define a method that will be initiated from created() method on load:
3.然后在要监视的页面上加载的VueJs组件中,定义一个将在加载时从created()方法启动的方法:
listenForBroadcast(survey_id) {
Echo.join('survey.' + survey_id)
.here((users) => {
this.users_viewing = users;
this.$forceUpdate();
})
.joining((user) => {
if (this.checkIfUserAlreadyViewingSurvey(user)) {
this.users_viewing.push(user);
this.$forceUpdate();
}
})
.leaving((user) => {
this.removeViewingUser(user);
this.$forceUpdate();
});
},
I obviously pulled some code out of the context here but I have this ‘users_viewing’ array to keep my current users that joined the channel.
我显然在这里从上下文中拉出了一些代码,但是我有这个'users_viewing'数组来保持我当前加入频道的用户。
And that would be it really.
就是这样。
Hope you were able to follow as I tried to be detailed as I can.
希望您能够按照我的建议尽可能详细地了解。
Happy coding!
编码愉快!
Follow me on TwitterAdd me on LinkedIn
翻译自: https://www.freecodecamp.org/news/how-to-use-laravel-with-socket-io-e7c7565cc19d/