Laravel 广播消息

简介配置 redis + socket 配置广播消息。

后端

  • 安装 predis/predis composer require predis/predis
  • 去掉 config/app 中的注释;
App\Providers\BroadcastServiceProvider::class
  • 设置 .env
BROADCAST_DRIVER=redis
  • 创建发送公共消息事件 app/Events/MessageSend.php
class MessageSend implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $message;
    public function __construct($message)
    {
        $this->message = $message;
    }
    public function broadcastAs()
    {
        return 'message.send';
    }
    public function broadcastOn()
    {
        return new Channel('message.send');
    }
}
  • 创建发送私人消息事件;
class PrivateMessageSend implements ShouldBroadcast
{
   use Dispatchable, InteractsWithSockets, SerializesModels;
   public $toUserId;
   public $message;
   public function __construct($toUserId, $message)
   {
       $this->toUserId = $toUserId;
       $this->message = $message;
   }
   public function broadcastAs()
   {
       return 'private.message.send';
   }
   public function broadcastOn()
   {
       return new PrivateChannel('private.message.send.' . $this->toUserId);
   }
}
// routes/channels.php
Broadcast::channel('private.message.send.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});
  • 创建 command 来测试;
class SendMessage extends Command
{
    protected $signature = 'message:send {user=0}';
    protected $description = 'Command description';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        $userId = intval($this->argument('user'));
        $message = "hello";
        if($userId > 0) {
            event(new PrivateMessageSend($userId, $message)); // 触发事件
        } else {
            event(new MessageSend($message)); // 触发事件
        }

        $this->info('发送消息 : ' . json_encode($message) );
    }
}

前端

  • 安装 redis 详见
  • 安装 laravel-echo-server npm install -g laravel-echo-server
    • 在主目录中执行 laravel-echo-server init 创建配置文件
{
	"authHost": "http://localhost",
	"authEndpoint": "/broadcasting/auth",
	"clients": [],
	"database": "redis",
	"databaseConfig": {
		"redis": {},
		"sqlite": {
			"databasePath": "/database/laravel-echo-server.sqlite"
		}
	},
	"devMode": false,
	"host": null,
	"port": "6001",
	"protocol": "http",
	"socketio": {},
	"sslCertPath": "",
	"sslKeyPath": "",
	"sslCertChainPath": "",
	"sslPassphrase": "",
	"apiOriginAllow": {
		"allowCors": false,
		"allowOrigin": "",
		"allowMethods": "",
		"allowHeaders": ""
	}
}
  • 安装 Laravel Echo npm install --save laravel-echo
  • 安装 socket.io-client npm install --save socket.io-client
  • 创建 socket 服务
//src/app/core/socket/socket.service.ts
import { Inject, Injectable } from '@angular/core';
import { environment } from '@env/environment';
import Echo from 'laravel-echo'
import { DA_SERVICE_TOKEN, TokenService } from '@delon/auth';
import { LayoutModule } from '../../layout/layout.module';
import { NzMessageService } from 'ng-zorro-antd';
import { SettingsService } from '@delon/theme';
(<any>window).io = require('socket.io-client');
@Injectable()
export class SocketService {
  echo: any;
  constructor(
    private settingService :SettingsService,
    @Inject(DA_SERVICE_TOKEN) private tokenService: TokenService) { }
  public init(): void {
    if (!environment.production) {
      console.log(
        `%c SOCKET: 初始化 `,
        `background:blue;color:#fff`,
      );
    }
    // 记得获取新的token后也要更新
    let token = this.tokenService.get().token;
    this.echo = new Echo({
      broadcaster: 'socket.io',
      host: window.location.hostname + ':6001',
      auth: {headers: {Authorization: 'Bearer ' + token}}
    });
  }
  public destroy() :void {
    if(!this.echo) return;
    let userId = this.settingService.user.id;
    this.echo.leave(`message.send`);
    this.echo.leave(`private.message.send.${userId}`);
    this.echo.disconnect();
  }
}
  • 在 app.module.ts 的 providers 中添加 SocketService
  • 在 startup 初始化最后添加 socket 服务的初始化操作
this.socketService.init();
  • 在 src/index.html 中添加
 <script type="text/javascript" src="http://localhost:6001/socket.io/socket.io.js"></script>
  • 在 src/polyfills.ts 中添加
(window as any).global = window;

秋叶听风
请先登录后发表评论
  • latest comments
  • 总共0条评论