laravel 使用 websockets 时的最佳实践?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18966667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:28:19  来源:igfitidea点击:

Best practice when using websockets?

laravellaravel-4zeromqphpwebsocketratchet

提问by Hyman Sierkstra

I got a webapplication written in Laravel 4. This application makes use of Ratchet and to be more specific, it uses the package Latchet. As a sidenote I am using the following techniques :

我有一个用 Laravel 4 编写的网络应用程序。这个应用程序使用了 Ratchet,更具体地说,它使用了Latchet包。作为旁注,我正在使用以下技术:

Now I got the following scenario:

现在我得到了以下场景:

  • I have a slideshow which should receive updates through the websocket.
  • The whole application is setup and I can publish new code changes from PHP to my websocket clients through ZeroMq.
  • In my routes.php, I have the following code, so that a topic is registered correctly :

    //routes.php
    // Setup a connection and register a topic where clients can connect to.
    Latchet::connection('Connection');
    Latchet::topic('PhotoStream/{client}', 'PhotoStreamController');
    
  • Then, I start the ratchet server.

  • 我有一个幻灯片,它应该通过 websocket 接收更新。
  • 整个应用程序都设置好了,我可以通过 ZeroMq 将新的代码更改从 PHP 发布到我的 websocket 客户端。
  • 在我的 routes.php 中,我有以下代码,以便正确注册主题:

    //routes.php
    // Setup a connection and register a topic where clients can connect to.
    Latchet::connection('Connection');
    Latchet::topic('PhotoStream/{client}', 'PhotoStreamController');
    
  • 然后,我启动棘轮服务器。

sudo php artisan latchet:listen

sudo php artisan latchet:listen

When a photo gets uploaded, I can then run the following code to push updates to the clients that are listening to my topic (PhotoStream/client1in this case):

上传照片后,我可以运行以下代码将更新推送到正在收听我的主题的客户端(PhotoStream/client1在本例中):

// Create the object, save it to db and then publish it to my websockets
$photo = new Photo;
$photo->location = 'path/to/file';
$photo->save();
// Publish it through my websocket clients. (push from server).
Latchet::publish('PhotoStream/client1', array('msg' => $photo->toArray() ));

This code all works, but it is in case of an update. My question is as follows:

这段代码都有效,但它是在更新的情况下。我的问题如下:

How should I handle the initialisation of the client?

我应该如何处理客户端的初始化?

  1. Should I first render the page with plain old PHP and then initialize my websocket client which then receive further updates (if there are any)?.
  2. Or should I, when I register a new websocket client, give an extra parameter with the request so the server sends me the complete data through websockets?
  1. 我应该首先使用普通的旧 PHP 呈现页面,然后初始化我的 websocket 客户端,然后接收进一步的更新(如果有的话)?
  2. 或者我应该在注册新的 websocket 客户端时,在请求中提供一个额外的参数,以便服务器通过 websockets 向我发送完整的数据?

The latter of the two options seems the best option to me but I don't really know how to implement this in a good way.

这两个选项中的后者对我来说似乎是最好的选择,但我真的不知道如何以一种好的方式实现它。

回答by Eelke van den Bos

On the javascript side (to retrieve initial list):

在 javascript 方面(检索初始列表):

//session.subscribe(....)

session.call('route/to/controller', arg1, arg2).then(function(res) {
   console.log(res) //initial collection of photos
});

On the php side (to retrieve initial list):

在 php 端(检索初始列表):

public function call($connection, $id, $topic, $params) {
    //the id is needed to be able to trace your async calls back to the right promise
    $connection->callResult($id, $this->getInitialPhotosFilteredByParams($params));
});

Since you already successfully gotten updates via the subscribe, this is all you need. Watch out for xss though, params might not be filtred.

由于您已经通过订阅成功获得更新,这就是您所需要的。不过要注意 xss,参数可能不会被过滤。

回答by mitchken

If understood your question in the right way this is it: You are wondering if sending images over the websocket is a good idea if those images could also be preloaded form PHP.

如果以正确的方式理解您的问题,就是这样:您想知道通过 websocket 发送图像是否是一个好主意,如果这些图像也可以从 PHP 中预加载。

I would suggest you to use PHP to preload the images without using the websocket and would start using the socket once new images are being added.

我建议您在不使用 websocket 的情况下使用 PHP 预加载图像,并在添加新图像后开始使用套接字。

This way the user should see images from the moment the page is loaded and they will not have to wait for the websocket connection to be established.

这样用户应该从页面加载的那一刻开始看到图像,他们不必等待 websocket 连接建立。

If you prefer to do the loading over the socket I would still suggest you to load the first few images from the slider, that can be seen immediately, from PHP. Otherwise the user will have to wait longer(note that much, but noticeably longer still).

如果您更喜欢通过套接字加载,我仍然建议您从滑块加载前几张图像,这些图像可以立即从 PHP 中看到。否则用户将不得不等待更长的时间(注意很多,但明显更长)。