2017-09-22 195 views
3

我試圖創建一個使用Laravel作爲後端API客戶端和我的前端的SPA的實時通知系統,我使用React作爲前端,但是對於以下例如,我將使用我創建的簡單Vue.Js和刀片來獲取工作示例。Laravel使用Socket.io將廣播轉播到私人頻道

所以,這一切的一切,我有一個觸發事件的路線,這是顯示像下面的例子:

Route::get('fire', function() { 
    // this fires the event 
    $user = App\Models\User::find(1); 
    event(new App\Events\CampaignUploadedWithSuccess($user, 'testing a notification')); 
    return "event fired"; 
}); 

,它觸發看起來像這樣

<?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 CampaignUploadedWithSuccess implements ShouldBroadcast 
{ 
    protected $user; 

    public $notification; 

    use Dispatchable, InteractsWithSockets, SerializesModels; 

    /** 
    * Create a new event instance. 
    * 
    * @param $user 
    * @param $notification 
    */ 
    public function __construct($user, $notification) 
    { 
     $this->user = $user; 
     $this->notification = $notification; 
    } 

    /** 
    * Get the channels the event should broadcast on. 
    * 
    * @return Channel|array 
    */ 
    public function broadcastOn() 
    { 
     return ['notifications-channel.' . $this->user->id]; 
    } 
} 

事件所以我在一個名爲notification-channel.{userId}

的頻道上播出我有一個使用節點運行的socket.js文件。

這看起來像使用node socket.js

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
var Redis = require('ioredis'); 

var redis = new Redis(); 
redis.subscribe('notifications-channel.1', function(err, count) { 
}); 
redis.on('message', function(channel, message) { 
    console.log('Notification Recieved: ' + message); 
    message = JSON.parse(message); 
    io.emit(channel + ':' + message.event, message.data); 
}); 
http.listen(3000, function(){ 
    console.log('Listening on Port 3000'); 
}); 

運行在服務器和觸發事件做什麼,我要象下面這樣:

Notification Recieved on localhost:3000

快樂的日子!我向廣播信道..

不過,我現在有一個刀片文件調用test.blade將在Vue公司和Socket.io

,看起來像這樣

<!DOCTYPE html> 
<html> 
<head> 
    <title>Laravel</title> 
</head> 
<body> 
<h1>Notifications</h1> 

<ul> 
    <li v-repeat="notification: notifications">@{{ notifications }}</li> 
</ul> 

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.7/socket.io.min.js"></script> 

<script> 
    var socket = io('http://localhost:3000'); 
    new Vue({ 
     el: 'body', 
     data: { 
      notifications: [] 
     }, 
     ready: function() { 
      socket.on('notifications-channel.1', function(data) { 
       alert(data.notification); 
      }); 
     } 
    }); 
</script> 
</body> 
</html> 

和拉這裏的目標是在通知通道1有廣播數據時讓消息警報。然而這不起作用。

所以我的問題是,如何向頻道廣播並使用socket.io,Laravel和Redis從頻道中消費廣播。

我也有點在私人頻道的黑暗中,以及如何爲一位用戶創建頻道。該文檔很好,但它沒有提供如何實現這一目標的真實世界示例,並且有多個平臺使用通知。

回答

2

我也面臨着同樣的問題搜索,我發現這個問題是由於插座版之後。請確保您使用相同的socket.io版本同時在服務器端和客戶端,你可以先驗證此檢查中的package.json文件中的插座版本就像我的情況下,你可以看到下面

"devDependencies": { 
    "socket.io": "^2.0.3", 
    "socket.io-client": "^2.0.3", 
} 

然後驗證您測試的套接字版本。刀片文件如下

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> 

你可以看到這兩個版本都是一樣的。

並且您的刀片文件中存在一個問題,您可以通過key channel:event.name發送套接字事件,但在您的刀片文件中,只能監聽通道名稱,而不會連接事件名稱。請與下面的代碼

<script> 
    var socket = io('http://localhost:3000'); 
    new Vue({ 
     el: 'body', 
     data: { 
      notifications: [] 
     }, 
     ready: function() { 
      socket.on('notifications-channel.1:App\\Events\\CampaignUploadedWithSuccess', function(data) { 
       alert(data.notification); 
      }); 
     } 
    }); 
</script> 
+0

這使得有很大的意義代替它,所以我改變了葉片的文件,當我在瀏覽器中運行它,我看到我的H1標籤,說通知,控制檯顯示錯誤的連接拒絕,所以我運行節點socket.js和錯誤消失,在我的腦海裏,這意味着它連接到本地主機:3000,我解僱了事件,它顯示在服務器控制檯中,但不會控制檯登錄客戶端...我使版本匹配:) –

+0

我想我可能會錯過與我的socket.js文件中的套接字的連接 –

+0

您廣播您的事件的頻道具有名稱通知 - 然後動態地通過用戶標識並在客戶端上傳輸通道硬編碼它與1.你目前登錄的用戶有ID 1請你確認。 –

1

我認爲你缺少的IO外觀的設置在

https://socket.io/docs/server-api/

像這樣的事情就需要你的服務器的NodeJS和/或客戶端上。

​​

希望這有助於