laravel做一个聊天室可好?

不要重复造轮子,有稳定的扩展包!!!

不要重复造轮子,有稳定的扩展包!!!

不要重复造轮子,有稳定的扩展包!!!

扩展包

    “workerman/gateway-worker”: “^3.0”,

    “workerman/gatewayclient”: “^3.0”,

    “workerman/workerman”: “^4.0”

1.前端VUE组件

chat.vue

<template>
    <div class="flex flex-col w-full md:w-auto flex-fill flex-wrap" style="height:579px;">
        <div class="row-span-2 bg-gray-100 flex-1 overflow-y-auto message">
            <div v-for="(message,index) in messages" :key="index">
                <div>
                    <span class="bg-base-300 mx-2">{{ message.user.name }}</span>
                    <span>{{ message.content }}</span>
                </div>
            </div>
        </div>
        <div class="row-span-1 ">
            <div class="card p-3 bg-base-200">
                <div class="form-control">
                    <label class="label">
                        <span class="label-text">您的名字</span>
                    </label>
                    <input v-model="content" class="textarea h-12" name="content" onSubmit
                           placeholder="聊聊呗" type="textarea" @keyup.enter="onSubmit"
                    />
                    <button class="btn btn-primary mt-3" @click="onSubmit">发送</button>
                </div>
            </div>
        </div>
    </div>

</template>

<script>
export default {
    data() {
        return {
            client_id: '',
            messages: [],
            content: ''
        }
    },
    mounted() {
        let ws = new WebSocket("wss://live.yhdengdeng.net:8282");
        ws.onmessage = this.message
    },
    methods: {
        message({data}) {
            data = JSON.parse(data)
            switch (data.type) {
                case 'init':
                    this.client_id = data.client_id
                    axios.get('chat/init', this.$data)
                    break;
                default:
                    this.messages.push(data)
                    this.messages = this.messages.reverse().splice(0, 30).reverse()
                    this.$nextTick(_ => {
                        document.querySelector('.message').scrollTo({
                            top: 9999
                        })
                    })

            }
        },
        onSubmit() {
            if (this.content.trim()) {
                this.axios.post('chat/send', this.$data)

                this.content = ''
            }
        }
    }
}
</script>

<style scoped>
.message {
    height: 200px;
}
</style>

2.定义控制器:chatcontroller

<?php

namespace App\Http\Controllers;

use Auth;
use GatewayClient\Gateway;
use Illuminate\Http\Request;

class ChatController extends Controller
{

    public function __construct()
    {
        Gateway::$registerAddress = '127.0.0.1:1238';
    }

    public function init()
    {
        for ($i = 0; $i < 20; $i++)
            $this->sendToAll('进入直播间');

        return $this->success('操作成功');
    }

    public function send(Request $request)
    {
        if (Auth::user()) {
            $this->sendToAll($request->content);
            return $this->success('发送成功');

        } else {
            return $this->error('请登录再试');
        }

    }

    public function sendToAll($content)
    {
        //游客状态不让发消息
        if (Auth::user()) {
            Gateway::sendToAll(json_encode(
                [
                    'user' => Auth::user(),
                    'content' => $content
                ]
            ));
            return $this->success('发送成功');
        } else {
            return $this->error('请登录再试');
        }
    }
}

3.安装包

    “workerman/gateway-worker”: “^3.0”,

“workerman/gatewayclient”: “^3.0”,

        “workerman/workerman”: “^4.0”

4.配置

创建socket文件夹

目录结构如下:

    –App

       — Events.php

       –start_busnessworker.php

       — start_gateway.php

       — start_register.php

    –ssl //生成https证书

       server.key

       server.pem

    start.php

    4.1配置一

    

    Event.php

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */

//declare(ticks=1);

use GatewayWorker\Lib\Gateway;

/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     *
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        Gateway::sendToClient($client_id, json_encode([
            'type' => 'init',
            'client_id' => $client_id
        ]));

//        // 向当前client_id发送数据
//        Gateway::sendToClient($client_id, "@@@Hello $client_id\r\n");
//        // 向所有人发送
//        Gateway::sendToAll("$client_id login\r\n");
    }

    /**
     * 当客户端发来消息时触发
     * @param int $client_id 连接id
     * @param mixed $message 具体消息
     */
    public static function onMessage($client_id, $message)
    {
        // 向所有人发送
        Gateway::sendToAll("$client_id said $message\r\n");
    }

    /**
     * 当用户断开连接时触发
     * @param int $client_id 连接id
     */
    public static function onClose($client_id)
    {
        // 向所有人发送
        GateWay::sendToAll("$client_id logout\r\n");
    }
}

4.2配置二 start_businesworker.php

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

use GatewayWorker\BusinessWorker;
use Workerman\WebServer;
use Workerman\Worker;

// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';

// bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = 'YourAppBusinessWorker';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '127.0.0.1:1238';

// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}

4.3配置三start_gateway.php

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use Workerman\Autoloader;
use Workerman\WebServer;
use Workerman\Worker;

// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';

// 证书最好是申请的证书
$context = array(
    // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
    'ssl' => array(
        // 请使用绝对路径
        'local_cert' => __DIR__ . '/../ssl/server.pem', // 也可以是crt文件
        'local_pk' => __DIR__ . '/../ssl/server.key',
        'verify_peer' => false,
        // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
    )
);
// websocket协议(端口任意,只要没有被其它程序占用就行)
// 开启SSL,websocket+SSL 即wss


// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("websocket://0.0.0.0:8282", $context);
$gateway->transport = 'ssl';

// gateway名称,status方便查看
$gateway->name = '聊天室';
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '127.0.0.1';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = '127.0.0.1:1238';

// 心跳间隔
//$gateway->pingInterval = 10;
// 心跳数据
//$gateway->pingData = '{"type":"ping"}';

/*
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection)
{
    $connection->onWebSocketConnect = function($connection , $http_header)
    {
        // 可以在这里判断连接来源是否合法,不合法就关掉连接
        // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
        if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net')
        {
            $connection->close();
        }
        // onWebSocketConnect 里面$_GET $_SERVER是可用的
        // var_dump($_GET, $_SERVER);
    };
};
*/

// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}

4.4配置4start_register.php

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

use GatewayWorker\Register;
use Workerman\Worker;

// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';

// register 必须是text协议
$register = new Register('text://0.0.0.0:1238');

// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}

4.5 start.php

<?php
/**
 * run with command
 * php start.php start
 */

ini_set('display_errors', 'on');

use Workerman\Worker;

if (strpos(strtolower(PHP_OS), 'win') === 0) {
    exit("start.php not support windows, please use start_for_win.bat\n");
}

// 检查扩展
if (!extension_loaded('pcntl')) {
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}

if (!extension_loaded('posix')) {
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}

// 标记是全局启动
define('GLOBAL_START', 1);

require_once __DIR__ . '/../vendor/autoload.php';

// 加载所有Applications/*/start.php,以便启动所有服务
foreach (glob(__DIR__ . '/App/start*.php') as $start_file) {
    require_once $start_file;
}
// 运行所有服务
Worker::runAll();

5.开启php服务,(当然也可以定义laravel命令或者自动注册一个服务方式开启)

    命令行开启socket服务:php socket/start.php start       

© 版权声明
THE END
喜欢就支持一下吧
点赞15
分享
评论 抢沙发
袁浩的头像孙先森资源|专注优质网络资源教程分享孙先森资源教程

昵称

取消
昵称表情代码图片