Laravel8基于LaravelS实现弹幕弹幕功能

作者: 温新

分类: 【高性能PHP】

阅读: 2416

时间: 2021-04-29 15:48:00

前面学了基于Swoole实现视频弹幕功能,这篇文章就来实现一个基于Laravel8的视频弹幕功能。如果对webpack不熟悉,那么在安装vue-baberrage组件时可能会报错却不知如何解决。下面开始一步一步实现。

第一步:安装Laravel8

composer create-project laravel/laravel labarrage

第二步:Laravel8中使用vue

Laravel8如何使用vue,请参考 Laravel8中使用vue。

注意:安装vue时请使用 php artisan ui vue --auth

第三步:安装及安装vue-baberrage

安装vue及bootstrap

npm install

安装弹幕组件

npm install vue-baberrage --save

运行

npm run dev

如果遇到BREAKING CHANGE: webpack < 5 used to include 错误,请参考 Laravel8使用webpack报错的解决方法。

后续只要文件改动就需要重新编译,后续将不再复述。

第四步:安装LaravelS实现Websocket服务器

请参考 Laravel8使用laravel-s实现WebSocket服务器

第五步:项目中引入vue-baberrage组件

文件:resources/js/app.js 新增如下内容

import { vueBaberrage } from 'vue-baberrage'
Vue.use(vueBaberrage)


Vue.component('danmu-component', require('./components/DanmuComponent.vue').default);

第五步:编写文弹幕组件

后续实现代码根据 学院君 文章改动

位置:resources/js/components/DanmuComponent.vue

<template>
    <div id="danmu">
        <div class="stage">
            <vue-baberrage
                    :isShow = "barrageIsShow"
                    :barrageList = "barrageList"
                    :loop = "barrageLoop"
                    :maxWordCount = "60"
            >
            </vue-baberrage>
        </div>
        <div class="danmu-control">
            <div>
                <select v-model="position">
                    <option value="top">从上</option>
                    <option value="abc">从右</option>
                </select>
                <input type="text" style="float:left"  v-model="msg"/>
                <button type="button" style="float:left" @click="addToList">发送</button>
            </div>
        </div>
    </div>
</template>

<script>
    import { MESSAGE_TYPE } from 'vue-baberrage'

    export default {
        name: 'danmu',
        data () {
            return {
                msg: 'hello 自如初!',
                position: 'top',
                barrageIsShow: true,
                currentId: 0,
                barrageLoop: false,
                barrageList: []
            }
        },
        methods: {
            removeList () {
                this.barrageList = []
            },
            addToList () {
                if (this.position === 'top') {
                    this.barrageList.push({
                        id: ++this.currentId,
                        msg: this.msg + this.currentId,
                        barrageStyle: 'top',
                        time: 8,
                        type: MESSAGE_TYPE.FROM_TOP,
                        position: 'top'
                    })
                } else {
                    this.barrageList.push({
                        id: ++this.currentId,
                        msg: this.msg,
                        time: 15,
                        type: MESSAGE_TYPE.NORMAL
                    })
                }
            }
        }
    }
</script>
<style lang="scss" scoped>
    #danmu {
        text-align: center;
        color: #2c3e50;
    }
    .stage {
        height: 300px;
        width: 100%;
        background: #025d63;
        margin: 0;
        position: relative;
        overflow: hidden;
    }

    h1, h2 {
        font-weight: normal;
    }
    ul {
        list-style-type: none;
        padding: 0;
    }
    li {
        display: inline-block;
        margin: 0 10px;
    }

    a {
        color: #42b983;
    }

    .baberrage-stage {
        z-index: 5;
    }

    .baberrage-stage .baberrage-item.normal{
        color:#FFF;
    }
    .top{
        border:1px solid #66aabb;
    }
    .danmu-control{
        position: absolute;
        margin: 0 auto;
        width: 100%;
        bottom: 300px;
        top: 70%;
        height: 69px;
        box-sizing: border-box;
        text-align: center;
        display: flex;
        justify-content: center;
        div {
            width: 300px;
            background: rgba(0, 0, 0, 0.6);
            padding: 15px;
            border-radius: 5px;
            border: 2px solid #8ad9ff;
        }
        input,button,select{
            height:35px;
            padding:0;
            float:left;
            background:#027fbb;
            border:1px solid #CCC;
            color:#FFF;
            border-radius:0;
            width:18%;
            box-sizing: border-box;
        }
        select{
            height:33px;
            margin-top:1px;
            border: 0px;
            outline: 1px solid rgb(204,204,204);
        }
        input{
            width:64%;
            height:35px;
            background:rgba(0,0,0,.7);
            border:1px solid #8ad9ff;
            padding-left:5px;
            color:#FFF;
        }
    }
</style>

第六步:视图中使用组件

位置:resources/views/danmu.blade.php

@extends('layouts.app')

@section('content')
    <danmu-component></danmu-component>
@endsection

第七步:注册路由

Route::get('/danmu', function() {
    return view('danmu');
});

执行 npm run dev

第八步:编写websocket服务器

文件:App\Handlers\WebSocketHandler.php

<?php
namespace App\Handlers;

use Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface;
use Illuminate\Support\Facades\Log;
use Swoole\Http\Request;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;

class WebSocketHandler implements WebSocketHandlerInterface
{
    public function __construct()
    {
    }

    // 连接建立时触发
    public function onOpen(Server $server, Request $request)
    {
        Log::info('WebSocket 连接建立:' . $request->fd);
    }

    // 收到消息时触发
    public function onMessage(Server $server, Frame $frame)
    {
        // $frame->fd 是客户端 id,$frame->data 是客户端发送的数据
        Log::info("从 {$frame->fd} 接收到的数据: {$frame->data}");
        foreach($server->connections as $fd){
            if (!$server->isEstablished($fd)) {
                // 如果连接不可用则忽略
                continue;
            }
            $server->push($fd , $frame->data); // 服务端通过 push 方法向所有连接的客户端发送数据
        }
    }

    // 连接关闭时触发
    public function onClose(Server $server, $fd, $reactorId)
    {
        Log::info('WebSocket 连接关闭:' . $fd);
    }
}

第九步:laravels.php注册

文件:config/laravels.php

'websocket' => [
    'enable' => true,
    'handler' =>  \App\Handlers\WebSocketHandler::class,
],

第十步:启动

php bin/laravels start

这样就完成啦

2021-04-29

请登录后再评论