我的编程空间,编程开发者的网络收藏夹
学习永远不晚

TP5与基于workerman的GatewayWorker框架实战在线客服教程【即时通讯】

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

TP5与基于workerman的GatewayWorker框架实战在线客服教程【即时通讯】

一、前期准备 环境搭建

GatewayWorker手册页面直接下载demo(根据自己使用的环境下载)在这里插入图片描述
觉得我的不标准的话可以去哔哩哔哩上看看《码农技术社区》这位大佬的视频挺详细的我就是跟着视频学会的

下载出来是长这个样子的

在这里插入图片描述

运行的话直接双击start_for_win.bat就可以了,停止的话ctrl+c,再打y回车就可以了,如图:

启动的样子
在这里插入图片描述
停止的样子

在这里插入图片描述

首先把GatewayWorker复制到tp5的vendor里面,如图:

在这里插入图片描述
打开vendor/GatewayWorker/Applications/YourApp/start_gateway.php,把tcp协议改成Websocket

在这里插入图片描述
在这里插入图片描述

二、长连接实现群发,初次体验

然后随便找个模板,随便发个消息试试,如图:

在这里插入图片描述

实例代码:

var ws = new WebSocket("ws://127.0.0.1:8282");ws.onmessage = function(e){    console.log(e)}$(".send-btn").click(function(){    var content = $(".send-input").val();    ws.send(content)    $(".send-input").val("");})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、群发及客户端和socket服务器保持长连接双向消息推送

然后再稍微改动一下就可以得到一个有点小问题的聊天(也不能说问题因为是向所有人发送信息所以回自己哪里也会多一条信息)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码改动部分(改完Events.php一定要重启start_for_win.bat,否则不生效)

在这里插入图片描述

public static function onMessage($client_id, $message){    $message_data = json_decode($message,true);    if(!$message_data){       return;    }    switch($message_data['type']){        case 'say';        $data = [            'type' => 'text',            'id' => $client_id,            'data' => $message_data['data'],        ];        Gateway::sendToAll(json_encode($data));        return;    }    // 向所有人发送     // Gateway::sendToAll("$client_id said $message\r\n");}

页面js部分

在这里插入图片描述

var ws = new WebSocket("ws://127.0.0.1:8282");ws.onmessage = function(e){    // eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行。    // console.log(e)    var msg = eval("("+e.data+")");    // console.log(msg)    switch(msg.type){        case 'text':        var html = '
' +'' +''+msg.data+'' +'
'
$(".chat-content").append(html); return; }}$(".send-btn").click(function(){ var content = $(".send-input").val(); // var res = '{"data":"'+content+'","type":"say"}'; var res = { 'data':content, 'type':'say', }; //JSON.stringify json转字符串 ws.send(JSON.stringify(res)) var html = '
' +''+content+'' +'' +'
'
; $(".chat-content").append(html); $(".send-input").val("");})

四、长连接绑定客户id实现一对一聊天

消息通过用户id来发送信息,效果如图:

这里1给2发送了一个你好啊,2给1发了个我很好

在这里插入图片描述在这里插入图片描述

而3哪里啥都没有

在这里插入图片描述

首先呢获取你的id跟对方的id发给页面

在这里插入图片描述

public function index(){    $input = input('get.');                    //fromid个人id   toid 对方id    $this->assign(['fromid'=>$input['fromid'],'toid'=>$input['toid']]);    return $this->fetch();}

并在前台接受并传给终端告诉他我是谁又要发给谁

在这里插入图片描述

var fromid = {$fromid};//个人idvar toid = {$toid};//他人id// console.log(fromid)// console.log(toid)var ws = new WebSocket("ws://127.0.0.1:8282");ws.onmessage = function(e){    // eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行。    // console.log(e)    var msg = eval("("+e.data+")");    // console.log(msg)    switch(msg.type){        case 'init':            var bind = {                'type':'bind',                'fromid':fromid,            };            //JSON.stringify  json转字符串            ws.send(JSON.stringify(bind))        return        case 'text':            //判断是否是当前聊天对象 是的话才会展示                if(toid == msg.toid){                    var html = '
' +'' +''+msg.data+'' +'
'
$(".chat-content").append(html); } return; }}$(".send-btn").click(function(){ var content = $(".send-input").val(); // var res = '{"data":"'+content+'","type":"say"}'; var res = { 'data':content, 'type':'say', 'fromid':fromid, 'toid':toid, }; //JSON.stringify json转字符串 ws.send(JSON.stringify(res)) var html = '
' +''+content+'' +'' +'
'
; $(".chat-content").append(html); $(".send-input").val("");})

然后Events.php里面进行获取并绑定,还有发送信息绑定对方id,其他根据自己要求来 (改完Events.php一定要重启start_for_win.bat,否则不生效)

在这里插入图片描述

public static function onConnect($client_id)    {        // 向当前client_id发送数据         // Gateway::sendToClient($client_id, "Hello $client_id\r\n");        // 向所有人发送        // Gateway::sendToAll("$client_id login\r\n");                //向客户端client_id发送$send_data数据。如果client_id对应的客户端不存在或者不在线则自动丢弃发送数据        Gateway::sendToClient($client_id,json_encode([            'type'=>'init',            'client_id'=>$client_id,        ]));    }           public static function onMessage($client_id, $message)    {        $message_data = json_decode($message,true);        if(!$message_data){           return;        }        switch($message_data['type']){            case 'bind':                //为啥这个绑定不在一开始连接时触发的时候绑定,因为是一开始才会触发的绑定,给别人发的话还得刷新才行,所以就在发消息的时候绑定id                //将client_id与uid绑定,以便通过Gateway::sendToUid($uid)发送数据,通过Gateway::isUidOnline($uid)用户是否在线。                //uid解释:这里uid泛指用户id或者设备id,用来唯一确定一个客户端用户或者设备。                Gateway::bindUid($client_id,$message_data['fromid']);            return;            case 'say';                $data = [                    'type' => 'text',                    'data' => $message_data['data'],                    'fromid'=>$message_data['fromid'],                    'toid'=>$message_data['toid'],                    'time'=>time(),                ];                // 向uid绑定的所有在线client_id发送数据。                // 注意:默认uid与client_id是一对多的关系,如果当前uid下绑定了多个client_id,则多个client_id对应的客户端都会收到消息,这类似于PC QQ和手机QQ同时在线接收消息。                Gateway::sendToUid($message_data['toid'],json_encode($data));                // 向所有人发送                 // Gateway::sendToAll(json_encode($data));            return;        }        // 向所有人发送         // Gateway::sendToAll("$client_id said $message\r\n");    }

五、getwayworker长连接下的普通文本消息之聊天记录持久化

在这里插入图片描述
前台代码:

doctype html><html><head>    <meta charset="utf-8">    <meta name="format-detection" content="telephone=no" />    <title>沟通中title>    <link rel="stylesheet" type="text/css" href="__STATIC__/Gatewayworker/css/themes.css?v=2017129">    <link rel="stylesheet" type="text/css" href="__STATIC__/Gatewayworker/css/h5app.css">    <link rel="stylesheet" type="text/css" href="__STATIC__/Gatewayworker/fonts/iconfont.css?v=2016070717">    <script class="lazy" data-src="__STATIC__/Gatewayworker/js/jquery.min.js">script>    <script class="lazy" data-src="__STATIC__/Gatewayworker/js/dist/flexible/flexible_css.debug.js">script>    <script class="lazy" data-src="__STATIC__/Gatewayworker/js/dist/flexible/flexible.debug.js">script>head><body ontouchstart><div class='fui-page-group'><div class='fui-page chatDetail-page'>    <div class="chat-header flex">        <i class="icon icon-toleft t-48">i>        <span class="shop-titlte t-30">{$to.name}span>        <span class="shop-online t-26">span>        <span class="into-shop">进店span>    div>    <div class="fui-content navbar" style="padding:1.2rem 0 1.35rem 0;">        <div class="chat-content">            <p style="display: none;text-align: center;padding-top: 0.5rem" id="more"><a>加载更多a>p>            {foreach $chat_record as $k => $v}    <p class="chat-time"><span class="time">{$v.add_time}span>p>                {if $from.id == $v.fromid}                <div class="chat-text section-left flex">                                        <span class="char-img" style="background-image: url({$to.toux})">span>                    <span class="text"><i class="icon icon-sanjiao4 t-32">i>{$v.content}span>                div>                {else}                <div class="chat-text section-right flex">                    <span class="text"><i class="icon icon-sanjiao3 t-32">i>{$v.content}span>                                        <span class="char-img" style="background-image: url({$from.toux})">span>                div>                {/if}            {/foreach}        div>    div>    <div class="fix-send flex footer-bar">        <i class="icon icon-emoji1 t-50">i>        <input class="send-input t-28" maxlength="200">        <i class="icon icon-add t-50" style="color: #888;">i>        <span class="send-btn">发送span>    div>div>div><script>    var fromid = {$from.id};//发送者id    var toid = {$to.id};//接收者id    // console.log(fromid)    // console.log(toid)    //连接服务器    var ws = new WebSocket("ws://127.0.0.1:8282");    //调用的方法均在GatewayWorker/Applications/Events.php里面的生命周期函数里面规定    //作用与Worker::$onMessage回调相同,区别是只针对当前连接有效,也就是可以针对某个连接的设置onMessage回调。    ws.onmessage = function(e){        // eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行。        // console.log(e)        //获取他人发送来的信息        var msg = eval("("+e.data+")");        switch(msg.type){            case 'init':                //绑定id                var bind = {                    'type':'bind',                    'fromid':fromid,                };                //JSON.stringify  json转字符串  send执行异步连接操作。此方法会立刻返回。 向客户端发送数据                ws.send(JSON.stringify(bind))                //判断是否在线 发过去  //初次加载判断是否在线                var online = {                    'type':'online',                    'toid':toid,                    'fromid':fromid,                };                ws.send(JSON.stringify(online))                //聊天内容定位到最下面                $('.chat-content').scrollTop(3000);            return            //接受消息            case 'text':                //用当前他人id跟他人发送过的fromid来对比   判断是否是当前聊天对象 是的话才会展示                if(toid == msg.fromid){                    var html = '
' // +'' +'' +''+msg.data+'' +'
'
$(".chat-content").append(html); //聊天内容定位到最下面 $('.chat-content').scrollTop(3000); } return; //保存消息 从而消息持久化 case 'save': //发送消息更新在线状态 if(msg.isread == 2){ $('.shop-online').text('在线'); }else{ $('.shop-online').text('不在线'); } save_message(msg);//调用 保存聊天数据 方法 //聊天内容定位到最下面 $('.chat-content').scrollTop(3000); return; //判断是否在线 回调 case 'online': //初次加载判断是否在线 if(msg.status == 1){ $('.shop-online').text('在线'); }else{ $('.shop-online').text('不在线'); } return; } } //发送信息 $(".send-btn").click(function(){ var content = $(".send-input").val(); // var res = '{"data":"'+content+'","type":"say"}'; var res = { 'data':content, 'type':'say', 'fromid':fromid, 'toid':toid, }; //聊天内容定位到最下面 $('.chat-content').scrollTop(3000); //JSON.stringify json转字符串 ws.send(JSON.stringify(res)) var html = '
' +''+content+'' // +'' +'' +'
'
; $(".chat-content").append(html); $(".send-input").val(""); }) //保存聊天数据 function save_message(data){ $.ajax({ type: "POST", url: "{:url('Gatewayworker/save_message')}", dataType: "json", data:{data}, success: function(res) {} }) }
script>body>html>

后台代码:

namespace app\index\controller;use think\Db;use think\Controller;class Gatewayworker extends Controller{    //聊天页面    public function index(){        $input = input('get.');        //fromid 发送者id   toid 接收者id        $from = db('admin')->where('id',$input['fromid'])->field('id,name,toux')->find();        $to = db('admin')->where('id',$input['toid'])->field('id,name,toux')->find();        //聊天记录   (不完美,除了二者的聊天记录别人的只要满足条件的也会显示出来)        $chat_record = db('chat_record')        ->where(['fromid'=>$input['fromid'],'toid'=>$input['toid']])        ->whereOr(['fromid'=>$input['toid'],'toid'=>$input['fromid']])        ->page(1,10)        ->order('chat_record_id')        ->select();        // halt($chat_record);        foreach($chat_record as $k => $v){            $chat_record[$k]['add_time'] = date('Y-m-d H:i:s',$v['add_time']);        }        $this->assign(['from'=>$from,'to'=>$to,'chat_record'=>$chat_record]);        return $this->fetch();    }    //保存聊天数据    public function save_message(){        $input = input('post.data');        $data=[            'fromid'=>$input['fromid'],            'fromname'=>$this->getname($input['fromid']),//获取发送者name            'toid'=>$input['toid'],            'toname'=>$this->getname($input['toid']),//获取接收者name            'content'=>$input['data'],            'add_time'=>$input['time'],            'isread'=>$input['isread'],//消息是否在线(1在线 2下线)            'type'=>1,//消息类型(1文本消息 2图片 )        ];        db('chat_record')->insert($data);    }    //获取发送者或接收者name    public function getname($id){        $data = db('admin')->where('id',$id)->field('id,name')->find();        return $data['name'];    }    }

Events.php里面的代码:

//declare(ticks=1);use \GatewayWorker\Lib\Gateway;/修改了这个文件一定要重启,否则不起作用class Events{        public static function onConnect($client_id)    {        // 向当前client_id发送数据         // Gateway::sendToClient($client_id, "Hello $client_id\r\n");        // 向所有人发送        // Gateway::sendToAll("$client_id login\r\n");                //向客户端client_id发送$send_data数据。如果client_id对应的客户端不存在或者不在线则自动丢弃发送数据        Gateway::sendToClient($client_id,json_encode([            'type'=>'init',            'client_id'=>$client_id,        ]));    }           public static function onMessage($client_id, $message)    {        //把前台发送过来的字符串转成数组        $message_data = json_decode($message,true);        if(!$message_data){           return;        }        switch($message_data['type']){            //绑定id            case 'bind':                //为啥这个绑定不在一开始连接时触发的时候绑定,因为是一开始才会触发的绑定,给别人发的话还得刷新才行,所以就在发消息的时候绑定id                //将client_id与uid绑定,以便通过Gateway::sendToUid($uid)发送数据,通过Gateway::isUidOnline($uid)用户是否在线。                //uid解释:这里uid泛指用户id或者设备id,用来唯一确定一个客户端用户或者设备。                Gateway::bindUid($client_id,$message_data['fromid']);            return;            case 'online':                //初次加载 判断接收者是否在线                $status = Gateway::isUidOnline($message_data['toid']);                $data=[                    'type'=>'online',                    'status'=>$status,                ];                // 向uid绑定的所有在线client_id发送数据。                // 注意:默认uid与client_id是一对多的关系,如果当前uid下绑定了多个client_id,则多个client_id对应的客户端都会收到消息,这类似于PC QQ和手机QQ同时在线接收消息。                //给发送者发送过去告诉他接收者是否在线                Gateway::sendToUid($message_data['fromid'],json_encode($data));return;            //发送消息   数据保存            case 'say';                $data = [                    'type' => 'text',//文本类型                    'data' => $message_data['data'],//发送内容                    'fromid'=>$message_data['fromid'],//发送者id                    'toid'=>$message_data['toid'],//接收者id                    'time'=>time(),//当前时间                ];                //判断接收者是否在线  //发送消息更新在线状态                if(Gateway::isUidOnline($message_data['toid'])){                    $data['isread'] = 2;//在线                    // 向uid绑定的所有在线client_id发送数据。                    // 注意:默认uid与client_id是一对多的关系,如果当前uid下绑定了多个client_id,则多个client_id对应的客户端都会收到消息,这类似于PC QQ和手机QQ同时在线接收消息。                    Gateway::sendToUid($message_data['toid'],json_encode($data));                }else{                    $data['isread'] = 1;//不在线                }                //类型设置为保存                $data['type']='save';                //告诉发送者 保存聊天数据 从来保证数据持久化 (workerman官方建议这里只写发送消息逻辑,所以保存到数据库交给前台ajax来)                Gateway::sendToUid($message_data['fromid'],json_encode($data));                // 向uid绑定的所有在线client_id发送数据。                // 注意:默认uid与client_id是一对多的关系,如果当前uid下绑定了多个client_id,则多个client_id对应的客户端都会收到消息,这类似于PC QQ和手机QQ同时在线接收消息。                // Gateway::sendToUid($message_data['toid'],json_encode($data));                // 向所有人发送                 // Gateway::sendToAll(json_encode($data));            return;        }        // 向所有人发送         // Gateway::sendToAll("$client_id said $message\r\n");    }          public static function onClose($client_id)    {       // 向所有人发送     //    GateWay::sendToAll("$client_id logout\r\n");    }}

来源地址:https://blog.csdn.net/qq_44678350/article/details/125521558

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

TP5与基于workerman的GatewayWorker框架实战在线客服教程【即时通讯】

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录