首页 > 解决方案 > Laravel 中的 Websocket 聊天不是实时的

问题描述

我正在 Laravel Websocket 中创建一个聊天,我遵循了一个 youtube 教程,消息发送给其他用户,他们可以互相交谈,但我需要重新加载页面以获取发送的消息,它不是实时的。在控制台在我发送消息之前它说这个错误:加载资源失败:服务器响应状态为 404(未找到),然后发送后说这个POST http://127.0.0.1:8000/broadcasting/auth 404(未找到)。我已经在终端中运行了“php artisan websocket:serve”命令。提前致谢

聊天控制器.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Message;
use App\Events\MessageSent;

class ChatsController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');//only authenticated users can acces to chat
    }

    public function index()
    {
        return view('chats');
    }

    public function fetchMessages()
    {
        return Message::with('user')->get();
    }

    public function sendMessage(Request $request)
    {
        $message = auth()->user()->messages()->create([
            'message' => $request->message
        ]);

        broadcast(new MessageSent($message->load('user')))->toOthers();

        return ['status' => 'success'];
    }
}

用户.php

    public function messages()
    {
        return $this->hasMany(Message::class);
    }

消息.php

    public function user()
    {
        return $this->belongsTo(User::class);
    }

网页.php

<?php
use App\User;
use App\Department;

use App\Events\WebsocketDemoEvent;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    broadcast(new WebsocketDemoEvent('some data'));
    return view('welcome');
});
Route::get('/page', function () {
    return view('admin.page');
});
Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');
Route::group(['middleware' => ['auth','admin']], function  () {
    Route::get('/role-register','Admin\DashboardController@registered');
    Route::delete('/role-delete/{id}', 'Admin\DashboardController@registerdelete');//delete user
    Route::post('/save-user', 'Admin\DashboardController@store');

    Route::get('/department', 'Admin\DepartmentController@index');
    Route::post('/save-department', 'Admin\DepartmentController@store');
    Route::get('/department-edit/{id}', 'Admin\DepartmentController@edit');//edit department
    Route::put('/department-update/{id}', 'Admin\DepartmentController@update');
    Route::delete('/department-delete/{id}', 'Admin\DepartmentController@delete');//delete department  


});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');

Route::get('/chats', 'ChatsController@index');//chats
Route::get('/messages', 'ChatsController@fetchMessages');//messages
Route::post('/messages', 'ChatsController@sendMessage');//messages

Route::get('/dashboard', 'Admin\DashboardController@dbcheck');//DATABASE
Route::get('/user-edit/{id}', 'HomeController@registeredit');
Route::get('/role-edit/{id}', 'Admin\DashboardController@registeredit');//edit user
Route::put('/role-register-update/{id}', 'Admin\DashboardController@registerupdate');

Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');


Route::get('store_image', 'StoreImageController@index');
Route::post('store_image/insert_image', 'StoreImageController@insert_image');
Route::get('store_image/fetch_image/{id}', 'StoreImageController@fetch_image');
Route::get('/page',array('as'=>'jquery.treeview','uses'=>'Admin\DepartmentController@treeView'));
Route::get('/pageusers', 'Admin\DepartmentController@usersdep');




聊天组件.vue

<template>
  <div class="row">

    <div class="col-8">
      <div class="card card-default">
        <div class="card-header">Messages</div>
        <div class="card-body p-0">
          <ul class="list-unstyled" style="height:300px; overflow-y:scroll">
            <li class="p-2" v-for="(message, index) in messages" :key="index">
              <strong>{{ message.user.name }}</strong>
              {{  message.message }}
            </li>
          </ul>
        </div>
        <input
        @keyup.enter="sendMessage"
        v-model="newMessage"
        type="text"
        name="message"
        placeholder="Enter your message"
        class="form-control">

      </div>
      <span class="text-muted">user is typing...</span>
    </div>

    <div class="col-4">
      <div class="card card-default">
        <div class="card-header">Active Users</div>
        <div class="card-body">
          <ul>
            <li class="py-2">{{ user.name }}</li>
          </ul>
        </div>
      </div>
    </div>

  </div>
</template>

<script>
export default {

  props:['user'],

  data() {
    return {
      messages: [],
      newMessage:''
    }

  },

  created() {
    this.fetchMessages();

    Echo.join('chat')
        .listen('MessageSent',(event) => {
        this.messages.push(event.message);
        })
  },

  methods: {
    fetchMessages() {
      axios.get('messages').then(response => {
        this.messages = response.data;
      })

    },

    sendMessage(){
      this.messages.push({
        user: this.user,
        message: this.newMessage

      });
      axios.post('messages', {message: this.newMessage});

      this.newMessage = '';
    }

  }

}
</script>

消息发送.php

<?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;
use App\Message;

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

    public $message;

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

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

标签: phplaravelwebsocket

解决方案


很抱歉将其发布为答案,但您需要 50 声望才能发表评论。您是否取消了config/app.phpApp\Providers\BroadcastServiceProvider::class,中的注释?


推荐阅读