之前有说过要整理出一篇事件广播的教程,今天终于有时间把这篇文章给写了出来,本次的教程是基于Laravel+Pusher+Vue,以事件广播作为核心技术,让你可以快速搭建起一个实时聊天室应用,话不多说,让我们来直接看看具体的内容吧。

应用初始化

安装配置

首先还是通过 Composer 安装一个全新的聊天室应用:composer create-project laravel/laravel chatroom --prefer-dist

由于要用到事件广播,所以需要取消 config/app.php 中广播服务提供者前面的注释:

修改 .env 中 BROADCAST_DRIVER 配置项为 pusher:

BROADCAST_DRIVER=pusher

尽管 Laravel 开箱支持 Pusher,但是我们还是需要安装对应的 PHP SDK:composer require pusher/pusher-php-server

设置 Pusher 凭证信息

访问 Pusher 官网,注册并登录到用户后台,创建一个新的 Channels App:

创建完成后即可在跳转页面中获取到 App Keys 相关信息:

将对应字段填充到聊天室应用根目录下的 .env 相应配置项即可。

前端资源初始化

我们使用 Laravel Mix 来编译前端 CSS 和 JavaScript:npm install

此外,Laravel 还提供了 JavaScript 库 Laravel Echo 来订阅和监听事件:npm install --save laravel-echo pusher-js

安装完成,还要告知 Laravel Echo 使用 Pusher,Laravel 已经在 resources/assets/js/bootstrap.js 中为我们提供了该实现,只不过默认注释起来了,只需要取消这段注释即可:import Echo from 'laravel-echo'

window.Pusher = require('pusher-js');

window.Echo = new Echo({

broadcaster: 'pusher',

key: process.env.MIX_PUSHER_APP_KEY,

cluster: process.env.MIX_PUSHER_APP_CLUSTER,

encrypted: true

});

用户认证脚手架代码

我们设定只有登录用户才能进入聊天室进行聊天,为了简化流程,我们使用 Laravel 默认的用户认证功能:php artisan make:auth

上述命令会为我们生成用户认证系统所必须的路由、视图、控制器等代码。在功能生效之前,还需要运行数据库迁移命令生成对应数据表,编辑 .env 中数据库相关配置项,保证可以正确连接上数据库,然后运行以下命令:php artisan migrate

至此,应用初始化准备工作已完成,下面开始编写业务代码。

业务代码实现

消息模型

首先要为发送的消息创建一个模型类及其对应数据库迁移文件:php artisan make:model Message -m

在新生成的 app/Messaage 模型类中新增下面这行代码以方便批量赋值:/**

* Fields that are mass assignable

*

* @var array

*/

protected $fillable = ['message'];

然后在 databases/migrations 目录下编写刚生成的 messages 对应迁移文件的 up 方法:Schema::create('messages', function (Blueprint $table) {

$table->increments('id');

$table->integer('user_id')->unsigned();

$table->text('message');

$table->timestamps();

});

最后执行迁移命令生成数据表 messages:php artisan migrate

用户与消息的关联关系

很显然,用户与消息之间是一对多的关系,在 User 模型类中新增关联方法:/**

* A user can have many messages

*

* @return \Illuminate\Database\Eloquent\Relations\HasMany

*/

public function messages()

{

return $this->hasMany(Message::class);

}

接下来在 Message 模型类中定义与之相对的关联关系:/**

* A message belong to a user

*

* @return \Illuminate\Database\Eloquent\Relations\BelongsTo

*/

public function user()

{

return $this->belongsTo(User::class);

}

控制器代码

创建控制器 ChatsController 实现具体业务逻辑:php artisan make:controller ChatsController

编写刚生成的控制器类 app/Http/Controllers/ChatsController 代码如下:<?php

namespace App\Http\Controllers;

use Auth;

use App\Message;

use Illuminate\Http\Request;

use Illuminate\Http\Response;

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)

{

$user = Auth::user();

$message = $user->messages()->create([

'message' => $request->input('message')

]);

return ['status' => 'Message Sent!'];

}

}

该控制器提供了三个业务方法,index 用于显示聊天室视图,fetchMessages 用户获取所有消息,sendMessage 用于发送消息。

注册应用路由

对应地,我们在 routes/web.php 中注册三个路由:Route::get('/', 'ChatsController@index');

Route::get('messages', 'ChatsController@fetchMessages');

Route::post('messages', 'ChatsController@sendMessage');

从注册路由中移除 /home 路由,相应地,需要把 app/Http/Controllers/Auth/LoginController.php 和 app/Http/Controllers/Auth/RegisterController.php 中的 $redirectTo 属性进行调整:protected $redirectTo = '/';

聊天室视图

对于聊天室视图代码,我们基于 Bootsnipp 聊天室代码片段 稍作调整。首先创建 resources/views/chat.blade.php:@extends('layouts.app')

@section('content')

聊天室

v-on:messagesent="addMessage"

:user="{{ Auth::user() }}"

>

@endsection

该视图用于展示聊天室主体页面。注意到我们在视图中使用了一些 Vue 组件,chat-messages 组件用于显示所有聊天信息,chat-form 组件用于发送消息,稍后会给出这些组件代码。

在编写 Vue 组件之前,我们在 resources/views/layouts/app.blade.php 模板中为 chat 视图添加一些样式代码(添加到 标签之前):

.chat {

list-style: none;

margin: 0;

padding: 0;

}

.chat li {

margin-bottom: 10px;

padding-bottom: 5px;

border-bottom: 1px dotted #B3A9A9;

}

.chat li .chat-body p {

margin: 0;

color: #777777;

}

.panel-body {

overflow-y: scroll;

height: 350px;

}

::-webkit-scrollbar-track {

-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);

background-color: #F5F5F5;

}

::-webkit-scrollbar {

width: 12px;

background-color: #F5F5F5;

}

::-webkit-scrollbar-thumb {

-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);

background-color: #555;

}

接下来在 resources/assets/js/components 中创建 ChatMessages.vue 组件:

  • {{ message.user.name }}

    {{ message.message }}

export default {

props: ['messages']

};

然后在同一目录下创建 ChatForm.vue 组件:

发送

export default {

props: ['user'],

data() {

return {

newMessage: ''

}

},

methods: {

sendMessage() {

this.$emit('messagesent', {

user: this.user,

message: this.newMessage

});

this.newMessage = ''

}

}

}

最后我们需要将这两个组件注册到位于 resources/assets/js/app.js 中的 Vue 根实例中:require('./bootstrap');

window.Vue = require('vue');

Vue.component('chat-messages', require('./components/ChatMessages.vue'));

Vue.component('chat-form', require('./components/ChatForm.vue'));

const app = new Vue({

el: '#app',

data: {

messages: []

},

created() {

this.fetchMessages();

},

methods: {

fetchMessages() {

axios.get('/messages').then(response => {

this.messages = response.data;

});

},

addMessage(message) {

this.messages.push(message);

axios.post('/messages', message).then(response => {

console.log(response.data);

});

}

}

});

广播消息发送事件

为了在聊天室中进行实时交互,需要广播某些事件,在本例中,我们会在用户发送消息时触发 MessageSent 事件:php artisan make:event MessageSent

编写 app/Events/MessageSent 事件类代码如下:<?php

namespace App\Events;

use App\Message;

use App\User;

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 MessageSent implements ShouldBroadcast

{

use Dispatchable, InteractsWithSockets, SerializesModels;

/**

* User that sent the message

*

* @var User

*/

public $user;

/**

* Message details

*

* @var Message

*/

public $message;

/**

* Create a new event instance.

* @param User $user

* @param Message $message

* @return void

*/

public function __construct(User $user, Message $message)

{

$this->user = $user;

$this->message = $message;

}

/**

* Get the channels the event should broadcast on.

*

* @return \Illuminate\Broadcasting\Channel|array

*/

public function broadcastOn()

{

return new PrivateChannel('chat');

}

}

由于只有登录用户才能访问我们的应用,所以我们定义了一个私有的频道 chat,只有登录用户才能连接上它。

接下来,我们需要修改 ChatsController 的 sendMessage() 来广播 MessageSent 事件:public function sendMessage(Request $request)

{

$user = Auth::user();

$message = $user->messages()->create([

'message' => $request->input('message')

]);

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

return ['status' => 'Message Sent!'];

}

然后在 routes/channels.php 中授权当前登录用户可以监听该私有频道:Broadcast::channel('chat', function ($user) {

return Auth::check();

});

现在,当一条消息发送后,MessageSent 事件就会被广播到 Pusher,使用 toOthers() 是为了将消息发送者从广播接收者中排除。

监听消息发送事件

MessageSent 事件在服务端被广播后,需要在客户端监听这个事件以便将最新发送消息更新到聊天室消息流中,我们可以通过在 resources/assets/js/app.js 中定义的 created() 方法中添加如下代码片段来实现这一功能:created() {

this.fetchMessages();

Echo.private('chat')

.listen('MessageSent', (e) => {

this.messages.push({

message: e.message.message,

user: e.user

});

});

},

我们通过 Laravel Echo 连接到 chat 频道监听 MessageSent 广播事件,如果有新消息则将其推送到当前聊天室消息流中显示。

在正式测试聊天室应用之前,还需要运行以下命令通过 Laravel Mix 来编译前面编写的 JavaScript 代码:npm run dev

使用示例

完成上述所有业务代码编写工作后,接下来就是见证工作成果的时候了,在项目根目录下运行如下命令启动应用:php artisan serve

然后在浏览器通过 http://127.0.0.1:8000/ 访问应用,由于系统需要登录后才能访问,所以首先会跳转到登录页面,我们需要先注册一个新用户,注册成功后页面即跳转到聊天室页面,我们发送一条测试消息。

为了测试多个用户聊天的效果,打开另一个浏览器或者在当前浏览器新开一个隐身窗口,还是重复上面的访问注册步骤(注册名不同),注册成功后跳转到聊天室页面,看到的效果和上面一样,我们再发条消息试试。

可以看到两个窗口消息是同步的,所以已经达到我们预期的实时聊天效果,实现了通过事件广播构建实时聊天室的功能。

以上就是本篇文章的全部内容了,更多laravel内容请关注laravel框架入门教程。

相关文章推荐:

相关课程推荐:

vue php聊天室,实时聊天室:基于Laravel+Pusher+Vue通过事件广播实现相关推荐

  1. pusher 创建新应用_基于 Laravel + Pusher + Vue 通过事件广播构建实时聊天室应用

    基于 Laravel + Pusher + Vue 通过事件广播构建实时聊天室应用 由 学院君 创建于2年前, 最后更新于 3个月前 版本号 #3 前言:学院君之前有说过要整理出一篇事件广播手把手教程 ...

  2. 基于 Laravel、Vue.js开发的全新社交系统----ThinkSNS+

    2019独角兽企业重金招聘Python工程师标准>>> ThinkSNS(简称TS)始于2008年,一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方 ...

  3. 微信小程序开发聊天室——实时聊天,支持图片预览

    第一次写小程序,老板就让我用websoket写个聊天对话,群聊这种.第一次写聊天功能,第一次用websoket,第一次用小程序,这是在考验我吗?不过我还是研究了一下,终于实现了. 首先看一下界面,界面 ...

  4. 实时聊天组合功能,你了解吗?

    你有兴趣安装实时聊天组合功能吗?如果您选择了SaleSmartly(ss客服),您的实时聊天插件可以不仅仅只是聊天通道,还可以有各种各样的功能,你不需要包含每一个功能,正所谓「宁缺勿滥」,功能越多,不 ...

  5. 如何选择最佳的实时聊天软件

    在客户服务和支持领域,实时聊天正在改变游戏规则已不是什么秘密.从推动销售到提升客户体验和提高保留率,实时聊天已成为与客户互动和支持的一种全新的方式.客户和支持专业人员都注意到了这一点. 研究发现,高达 ...

  6. SpringBoot实现分页查询——基于SpringBoot和Vue的后台管理系统项目系列博客(七)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  7. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  8. SpringBoot实现1对1、1对多、多对多关联查询——基于SpringBoot和Vue的后台管理系统项目系列博客(十八)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  9. 【毕设精选】基于SpringBoot和Vue的相关系统

    SpringBoot+Vue相关系统 前言 springboot330付费问答系统的设计与实现含文档附源码 springboot325基于Java的企业OA管理系统的设计与实现含文档附源码 sprin ...

最新文章

  1. Numpy掩码数组masked arrays,这一篇就够了
  2. R710后台更新网卡驱动
  3. php service原理,轻松搞懂WebService工作原理
  4. 第一篇 著名函数之单值函数
  5. Android --- .gradle文件夹的路径
  6. 结对编程小项目实现 Python+PyQt5+OOP
  7. REDIS实践之请勿踩多进程共用一个实例连接的坑
  8. mysql log table_mysqlbinlog功能扩展--table参数
  9. java getparametermap_重写getParameterMap后,报错 ,
  10. linux查找、搜索字符或文件
  11. UVA 11137 Ingenuous Cubrency (背包水题)
  12. vue Root file specified for compilation
  13. 【Android开发经验】Android相关问题的好文章整理——温故而知新,可以为师矣
  14. Phaser知识点总结
  15. 地震勘探原理(五)之地震勘探的野外工作
  16. eclipse 使用 firebase analysis sdk
  17. mybatisPlus根据起止时间作为条件进行查询
  18. linux安全清理缓存,架构师小跟班:如何高效又安全的清理Linux服务器上的缓存?...
  19. Domoticz 中接入斐讯 M1 空气质量检测仪
  20. Educational Codeforces Round 115 (Rated for Div. 2) A. Computer Game

热门文章

  1. ros环境下配置orb-slam2遇到的问题
  2. js删除数组中指定对象
  3. 方块 游戏界面java_JAva 判断方块游戏清除方法
  4. 【HDU 6411】带劲的and和 【并查集 + 二进制拆位】
  5. 《房债》书中的精髓:现代金融系统让全世界的人同处一艘经济大船上,一些人搞坏了船,所有的人都跟着遭殃。
  6. 【疑难杂症】Oculus Quest2 手机配对时找不到5-digit-code
  7. mong大牛的blog
  8. Mac M1芯片 安装vmware 和ubuntu 以及换源全过程
  9. 用混合编程实现两个LED交替闪烁
  10. 分享4个自媒体热门领域,选对了收入翻3倍