使用Pusher的Laravel WebSocket在进行POST请求时出现错误

5

我正在尝试将Web Socket集成到我的Laravel项目中。 我已经完成了这里的所有步骤。


composer require pusher/pusher-php-server
/Users/alpha/Sites/jdoe/config/broadcasting.php


https://dashboard.pusher.com/apps/888



app_id = "888"
key = "***"
secret = "333"
cluster = "us2"



|
V


BROADCAST_DRIVER=pusher
PUSHER_APP_ID=888
PUSHER_APP_KEY=***
PUSHER_APP_SECRET=333
PUSHER_APP_CLUSTER=us2


.env.example + .env 

npm install --save laravel-echo pusher-js


npm run watch 


---------------------------------------------------


php artisan make:event logEvent


<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class logEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    private $data;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('logEventChannel');
    }

    public function broadcastWith()
    {
        return [
            'data' => $this->data
        ];
    }
}

---------------------------------------------------



/Users/alpha/Sites/jdoe/resources/js/app.js



require('./bootstrap');


Echo.channel('logEventChannel').listen('logEvent', (e) => {

    // console.log(typeof JSON.parse(JSON.stringify(e))) //object
    // console.log(typeof JSON.parse(JSON.stringify(e.data))) //string
    // console.log(JSON.parse(e.data)); //decode or parse it

    let data = JSON.parse(e.data);

    /*=============================
    =            Debug            =
    =============================*/

    console.log('data ===== ',data);

    

});




---------------------------------------------------

route



Route::post('ws/log', 'BroadcastController@logEvent');




---------------------------------------------------
Controller



<?php

namespace App\Http\Controllers;

use App\Events\LogEvent;
use Illuminate\Http\Request;

class BroadcastController extends Controller
{

    public function vnfevent(Request $request)
    {

        $body            = json_decode($request->getContent(),true);
        dd($body); 
        $json = json_encode($body);

        broadcast(new LogEvent($json));

        return response()->json($body,200);

    }

}


---------------------------------------------------
CSRF


/Users/alpha/Sites/jdoe/app/Http/Middleware/VerifyCsrfToken.php


protected $except = [
'/ws/log'
];



---------------------------------------------------
TEST

POSTman

ws/log


{
    "type": "poop"
}



place a dd in broadbast 


arrived !! 

array:1 [
  "type" => "poop"
]




ErrorException: array_merge(): Expected parameter 2 to be an array, null given in file

---------------------------------------------------
Debug the crashing line 

/Users/alpha/Sites/jdoe/vendor/pusher/pusher-php-server/src/Pusher.php


dd($post_params, $params);
$all_params = array_merge($post_params, $params);




array:3 [▼
  "name" => "App\Events\logEvent"
  "data" => array:1 [▼
    "data" => "{"type":"poop"}"
  ]
  "channels" => array:1 [▼
    0 => "logEventChannel"
  ]
]


Look correct 


我测试了向我的/ws/log发送帖子

{
    "type": "poop"
}

我一直收到以下错误信息:

ErrorException: array_merge(): 预期参数 2 是数组,但给定的是 null,文件路径为 /Users/alpha/Sites/jdoe/vendor/pusher/pusher-php-server/src/Pusher.php,行数为 518

于是我打开了那个文件。

$all_params = array_merge($post_params, $params);

$params某种方式等于null

enter image description here

我该如何进一步调试这个问题?


编辑

我按照建议删除了我的vendor/目录,并尝试使用版本4.1。

"require": {
    "php": "^7.2.5",
    "doctrine/dbal": "^2.10",
    "fideloper/proxy": "^4.2",
    "fruitcake/laravel-cors": "^1.0",
    "guzzlehttp/guzzle": "^6.3",
    "intervention/image": "^2.3",
    "laravel/framework": "^7.0",
    "laravel/tinker": "^2.0",
    "laravelcollective/html": "~6.0",
    "pusher/pusher-php-server":"^4.1"
},

我在使用POSTman向我的路由发送POST请求时仍然遇到问题。

enter image description here

1个回答

8

针对这个问题,实际上这是 Laravel 中的一个问题,已经在 (Laravel 8.29.0) 或更高版本中解决了。
因此,pusher-http-php 库 v5.0.1 和 Laravel v8.29.0 将适合您使用。

另一种解决方案:是将 composer.json 中的 pusher 降级到版本 4.1,这个版本似乎可以与旧版 Laravel(早于 8.29.0)正常工作。

如果您想解决当前安装的问题:

问题在于 trigger 函数的调用,至少在 Laravel 8 上没有发送正确的参数,所以在 PusherBroadcaster.phppusher-php-server/Pusher.php 中有两个 trigger 函数的调用,它们是:

$this->pusher->trigger(
$this->formatChannels($channels), $event, $payload, $socket, true
);

并且

public function trigger($channels, $event, $data, $params = array(), $already_encoded = false)

你只需要更改 Pusher1- 更改 (第496行)。
$data_encoded = $this->crypto->encrypt_payload($channels[0], $already_encoded ? $data : json_encode($data));

To:

$data_encoded = $this->crypto->encrypt_payload($channels[0], $already_encoded && !is_array( $data) ? $data : json_encode($data));

2- 修改(第499行)。

$data_encoded = $already_encoded ? $data : json_encode($data);

To:

$data_encoded = $already_encoded && !is_array( $data) ? $data : json_encode($data);

3- 更改 (第518行)

$all_params = array_merge($post_params, $params);

To:

$all_params = array_merge($post_params, is_array($params) ? $params:[]);

4- 改变(第542行)

return $result;

To:

return $response;

请注意:

$param在这种情况下为null,并且代码没有检查此值是否为array(),因此当代码尝试将array()null合并时就会出现问题。

资源:

链接1 链接2 链接3

注:正如我所说,Laravel v8.29.0版本已经解决了这个问题。 链接
或者您可以使用 composer require pusher/pusher-php-server ^4.1

并且这将使它完美地为您工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接