简体   繁体   中英

laravel pusher run very slow

I followed this tutorial: BUILD A CHAT APP WITH LARAVEL

But the broadcast() and event() functions act very slow as 2~8 seconds when I track time duration in the php Controller. No Error messages launched by the way.

I guess it is not normal case, isn't websocket should works real-time? Even I changed DEBUG to true or false didn't change this.

I don't have an idea how fast laravel+pusher should be. They are just called as 'real-time', shouldn't they run in 0.0something second?

Could anyone give advice please?

** I just test it again. The broadcast time is ~0.8 second, and the whole duration from client sending POST to client's Listener handled broadcast is around 1 second. Sorry I can't reproduce the slow performance happened yesterday. Is this performance normal for Pusher? thanks!!

env:
Laravel Framework 5.6.28
laravel/homestead (virtualbox, 5.0.1)
laravel/homestead (virtualbox, 5.1.0)
laravel/homestead (virtualbox, 5.2.0)
laravel/homestead (virtualbox, 6.1.0)

php "^7.1.3"
barryvdh/laravel-debugbar   "^3.1"
fideloper/proxy "^4.0"
laravel/framework   "5.6.*"
laravel/tinker  "^1.0"
pusher/pusher-php-server    "^3.1"

below is my code:

<?php
//Controller
namespace App\Http\Controllers;

use App\Message;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Events\MessageSent;
use Debugbar as Debugbar;

class ChatsController extends Controller
{

public function __construct()
{
  $this->middleware('auth');
}

/**
 * Show chats
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
  return view('chat');
}

/**
 * Fetch all messages
 *
 * @return Message
 */
public function fetchMessages()
{
  return Message::with('user')->get();
}

/**
 * Persist message to database
 *
 * @param  Request $request
 * @return Response
 */
public function sendMessage(Request $request)
{
$t2 = microtime(true);
    $user = Auth::user();
//        DebugBar::info($user);

//$message = $user->messages()->create(['message' => $request->input('message')]);
$message = $user->messages()->create(['message' => $request->input('message')]);

DebugBar::info("logic time:");
DebugBar::info(microtime(true) - $t2);
//    $m = new Message(['message' => $request->input('message')]);
//    $user->messages()->create($message);
//    DebugBar::info($message);
$t1 = microtime(true);
//        broadcast(new MessageSent($user,$message));
        event(new MessageSent($user,$message));
DebugBar::info("broadcast time:");
DebugBar::info(microtime(true) - $t1);
  return ['status' => 'Message Sent!'];
}

    public function clearMessage(){
        $u = Auth::user();
        $m = $u->messages();
        $m->delete();
    }
}

<?php
//Event
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;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

use App\User;
use App\Message;

class MessageSent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
/**
 * The name of the queue on which to place the event.
 *
 * @var string
 */
public $broadcastQueue = 'your-queue-name';

    /**
     * User that sent the message
     *
     * @var User
     */
    public $user;

    /**
     * Message details
     *
     * @var Message
     */
    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
//    public function __construct(User $user, Message $message)
public function __construct(User $user, Message $message)
        {
        $this->user = $user;
//        $this->message = 'this is a message from MessageSent Class';
        $this->message = $message;
    }

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

<?php
// User
namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
 * A user can have many messages
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
    public function messages()
    {
        return $this->hasMany(Message::class);
    }

}

<?php
//Message
namespace App;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    //

    /**
 * Fields that are mass assignable
 *
 * @var array
 */
protected $fillable = ['message'];

/**
 * A message belong to a user
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function user()
{
  return $this->belongsTo(User::class);
}
}

 /** * First we will load all of this project's JavaScript dependencies which * includes Vue and other libraries. It is a great starting point when * building robust, powerful web applications using Vue and Laravel. */ require('./bootstrap'); window.Vue = require('vue'); //.... // chat example Vue.component('chat-messages', require('./components/ChatMessages.vue')); Vue.component('chat-form', require('./components/ChatForm.vue')); /** * Next, we will create a fresh Vue application instance and attach it to * the page. Then, you may begin adding components to this application * or customize the JavaScript scaffolding to fit your unique needs. */ let vm = new Vue({ el:'#app', data:{ name:'root', // // ... // // chat example messages: [], }, created(){ // chat example this.fetchMessages(); window.Echo.private('chat') .listen('MessageSent', (e) => { console.log('listened:'); console.log(e); this.messages.push({ message: e.message.message, user: e.user }); }); }, mounted(){ }, methods:{ // //... // // chat example fetchMessages() { axios.get('/messages').then(response => { this.messages = response.data; }); }, addMessage(message) { // this.messages.push(message); axios.post('/messages', message).then(response => { console.log('Post response:'); console.log(response.data); }); } }, components:{ 'top-nav-p': topNavP, 'slide-0': homeComponent, 'slide-1':gameListComponent, } }); 
 <!-- resources/views/chat.blade.php --> @extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">Chats</div> <div class="panel-body"> <chat-messages v-bind:messages="messages"></chat-messages> </div> <div class="panel-footer"> <chat-form v-on:messagesent="addMessage" :user="{{ Auth::user() }}" ></chat-form> </div> </div> </div> </div> </div> @endsection 

// resources/assets/js/components/ChatMessages.vue

<template>
    <ul class="chat">
        <li class="left clearfix" v-for="message in messages">
            <div class="chat-body clearfix">
                <div class="header">
                    <strong class="primary-font">
                        {{ message.user.name }}
                    </strong>
                </div>
                <p>
                    {{ getTime(message.message) }}
                </p>
            </div>
        </li>
    </ul>
</template>

<script>
  export default {
    props: ['messages'],
    methods: {
        getTime(m){
            return (performance.now()-m);
        }

    },
  };
</script>

// resources/assets/js/components/ChatForm.vue

<template>
    <div class="input-group">
        <input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Type your message here..." v-model="newMessage" @keyup.enter="sendMessage">

        <span class="input-group-btn">
            <button class="btn btn-primary btn-sm" id="btn-chat" @click="sendMessage">
                Send
            </button>
        </span>
    </div>
</template>
<script>
    export default {
        props: ['user'],

        data() {
            return {
                newMessage: ''
            }
        },

        methods: {
            sendMessage() {
                this.$emit('messagesent', {
                    user: this.user,
                    message: performance.now(),//this.newMessage
                });
                this.newMessage = ''
            }
        }
    }
</script>

I find out the default in queue.php point to sync , which is only for dev. After changing the default to database which is for production, the function broadcast() change to around 0.01 seconds.

Thanks for reading.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM