workerman结合laravel开发在线聊天应用

发布时间 - 2019-11-22 00:00:00    点击率:

下面由workerman php教程栏目给大家介绍workerman结合laravel开发在线聊天应用的方法,希望对需要的朋友有所帮助!

项目背景:

最近由于公司的业务需求,需要用到聊天功能。而且有比较多的个性化需求需要定制。之前使用别人的聊天组件是基于微擎的。如果要移植到普通的H5在逻辑修改还有定制上存在比较多的困难。为此只能克服困难,自己搭建一个吧

什么是Workerman?

Workerman是一款开源高性能异步PHP socket即时通讯框架。支持高并发,超高稳定性,被广泛的用于手机app、移动通讯,微信小程序,手游服务端、网络游戏、PHP聊天室、硬件通讯、智能家居、车联网、物联网等领域的开发。 

支持TCP长连接,支持Websocket、HTTP等协议,支持自定义协议。拥有异步Mysql、异步Redis、异步Http、MQTT物联网客户端、异步消息队列等众多高性能组件。

开始实战吧!

1.第一步我们先把workerman里需要用到的扩展composer下来吧

"workerman/gateway-worker": "^3.0",
"workerman/gatewayclient": "^3.0",
"workerman/workerman": "^3.5",

2.第二步我们到官方网站把demo全部下载下来,然后放到我们项目中的目录图片中我就把整个项目都放在了HTTP/Controller/Workerman中。

3.第三步我们需要把把以下3个文件的引用部分修改为以下。

不然会报路径错误

start_businessworker,start_gateway,start_register
require_once __DIR__ . '/../../../../../vendor/autoload.php';

4.修改完成后我们就可以在liunx直接运行对应的启动文件

php start.php start -d
如果你是在window下就双击start_for_win.bat运行

5.运行成功后,你就应该可以看到以下的界面到此我们搭建基于workerman的通信环境就已经完成。

接下来我们就可以根据自己的项目需求进行开发。

在此向大家重点说明。

我们所有的聊天是逻辑都在目录中的Events.php进行修改。


下面我给大家贴一下我编写的部分代码。

Event.php


 * @copyright walkor
 * @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);
/**
 * 聊天主逻辑
 * 主要是处理 onMessage onClose
 */
use \GatewayWorker\Lib\Gateway;
class Events
{
    /**
     * 作者:何志伟
     * 当客户端连接上来的时候
     * 创建时间:2018/10/25
     * @param $client_id 此ID为gatewayworker 自动生成ID
     */
    public static function onConnect($client_id)
    {
        Gateway::sendToClient($client_id, json_encode(array(
            'type'      => 'init',
            'client_id' => $client_id
        )));
    }
    /**
     * 有消息时
     * @param int $client_id
     * @param mixed $message
     */
    public static function onMessage($client_id, $message)
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
        // 客户端传递的是json数据
        $message_data = json_decode($message, true);
        if(!$message_data)
        {
            return ;
        }
        // 根据类型执行不同的业务
        switch($message_data['type'])
        {
            // 客户端回应服务端的心跳
            case 'pong':
                return;
            // 客户端登录 message格式: {type:login, name:xx, room_id:1} ,添加到客户端,广播给所有客户端xx进入聊天室
            case 'login':
                // 判断是否有房间号
                if(!isset($message_data['room_id']))
                {
                    throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                }
                // 把房间号昵称放到session中
                $room_id = $message_data['room_id'];
                $client_name = htmlspecialchars($message_data['client_name']);
                $_SESSION['room_id'] = $room_id;
                $_SESSION['client_name'] = $client_name;
                // 获取房间内所有用户列表
                $clients_list = Gateway::getClientSessionsByGroup($room_id);
                foreach($clients_list as $tmp_client_id=>$item)
                {
                    $clients_list[$tmp_client_id] = $item['client_name'];
                }
//                $clients_list[$client_id] = $client_name;
                // 转播给当前房间的所有客户端,xx进入聊天室 message {type:login, client_id:xx, name:xx}
                $new_message = array('type'=>$message_data['type'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'time'=>date('Y-m-d H:i:s'),'to'=>$message_data['to'],'room_id'=>$message_data['room_id'],
                    'from'=>$message_data['from'],'tag'=>$message_data['tag']);
                Gateway::sendToGroup($room_id, json_encode($new_message));
                Gateway::joinGroup($client_id, $room_id);
                // 给当前用户发送用户列表
                $new_message['client_list'] = $clients_list;
                Gateway::sendToCurrentClient(json_encode($new_message));
                return;
            // 客户端发言 message: {type:say, to_client_id:xx, content:xx}
            case 'say':
                // 非法请求
                if(!isset($_SESSION['room_id']))
                {
                    throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
                }
                $room_id = $_SESSION['room_id'];
                $client_name = $_SESSION['client_name'];
                // 私聊
//                if($message_data['to_client_id'] != 'all')
//                {
//                    $new_message = array(
//                        'type'=>'say',
//                        'from_client_id'=>$client_id,
//                        'from_client_name' =>$client_name,
//                        'to_client_id'=>$message_data['to_client_id'],
//                        'content'=>"对你说: ".nl2br(htmlspecialchars($message_data['content'])),
//                        'time'=>date('Y-m-d H:i:s'),
//                    );
//                    Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
//                    $new_message['content'] = "你对".htmlspecialchars($message_data['to_client_name'])."说: ".nl2br(htmlspecialchars($message_data['content']));
//                    return Gateway::sendToCurrentClient(json_encode($new_message));
//                }
                $new_message = array(
                    'type'=>'say',
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>'all',
                    'content'=>nl2br(htmlspecialchars($message_data['content'])),
                    'time'=>date('Y-m-d H:i:s'),
                );
                return Gateway::sendToGroup($room_id ,json_encode($new_message));
        }
    }
    /**
     * 当客户端断开连接时
     * @param integer $client_id 客户端id
     */
    public static function onClose($client_id)
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";
        // 从房间的客户端列表中删除
        if(isset($_SESSION['room_id']))
        {
            $room_id = $_SESSION['room_id'];
            $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
            Gateway::sendToGroup($room_id, json_encode($new_message));
        }
    }
}

客户端页面




    
    与{{$to->name}}的对话
    
    
    
    
    
    
    
    {{----}}




    
        {{--对话窗口头部--}}
        
            
                @@##@@heading}}" width="80px" height="40px">
            
            
                {{$to->name}}
            
        
        {{--//对话窗口内容--}}
        
            {{--对方的头像与文字--}}
            {{----}}
                {{----}}
                    {{--@@##@@heading}}" width="50px" height="50px">--}}
                {{----}}
                {{--dsadsadsadsadsa--}}
            {{----}}
            {{--我的头像与文字--}}
            {{----}}
                {{----}}
                    {{--@@##@@heading}}" width="50px" height="50px">--}}
                {{----}}
                {{--dsadsadsadsadsa--}}
            {{----}}
        
        {{--对话发送窗口--}}
        
房间号{{$room}}

复制代码这两个代码片段其实就是主要运行的核心片段。其他框架的自带参数需要各位自己去根据文档去调试优化。到此基于workerman的聊天用于功能demo已经搭建完毕。


# workerman  # php  # laravel  # composer  # mysql  # Event  # 并发  # 异步  # redis  # 微信小程序  # http  # websocket  # 物联网 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何发送系统通知?(Notification渠道示例)  LinuxShell函数封装方法_脚本复用设计思路【教程】  如何在Ubuntu系统下快速搭建WordPress个人网站?  微信小程序 HTTPS报错整理常见问题及解决方案  网站制作免费,什么网站能看正片电影?  javascript中对象的定义、使用以及对象和原型链操作小结  Swift中循环语句中的转移语句 break 和 continue  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  iOS UIView常见属性方法小结  怎么用AI帮你设计一套个性化的手机App图标?  Python数据仓库与ETL构建实战_Airflow调度流程详解  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  Bootstrap整体框架之JavaScript插件架构  Laravel怎么导出Excel文件_Laravel Excel插件使用教程  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  Laravel如何使用Vite进行前端资源打包?(配置示例)  如何在阿里云高效完成企业建站全流程?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  如何用美橙互联一键搭建多站合一网站?  Android自定义listview布局实现上拉加载下拉刷新功能  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】  Java解压缩zip - 解压缩多个文件或文件夹实例  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  JavaScript模板引擎Template.js使用详解  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何在万网自助建站平台快速创建网站?  如何快速搭建安全的FTP站点?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  公司门户网站制作流程,华为官网怎么做?  HTML 中动态设置元素 name 属性的正确语法详解  深入理解Android中的xmlns:tools属性  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  C语言设计一个闪闪的圣诞树  javascript中的try catch异常捕获机制用法分析  Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  如何在万网自助建站中设置域名及备案?  千库网官网入口推荐 千库网设计创意平台入口  Laravel如何实现事件和监听器?(Event & Listener实战)  如何快速查询域名建站关键信息?  Laravel中的Facade(门面)到底是什么原理  如何快速搭建高效WAP手机网站吸引移动用户?  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  香港服务器如何优化才能显著提升网站加载速度?  如何在阿里云域名上完成建站全流程?