1.下载安装tp5.1

composer create-project topthink/think=5.1.* tp5

2.去官方下载getway

getway下载https://www.workerman.net/doc/gateway-worker/        2.1. 下载后直接解压到tp5.1里即可,和application同级

3安装gatewayClient,建议使用composer

composer require workerman/gatewayclient

GatewayClient安装https://www.workerman.net/doc/gateway-worker/work-with-other-frameworks.html#GatewayClient%E5%AE%89%E8%A3%85

4. 因为我用的linux服务器,安装过程中可能会遇到某函数被禁用。解决办法:前往/www/server/php/72/etc/php.ini 找到被禁用的函数,被禁用的删掉即可。如图我被禁用的函数。

5.配置start_getway.php文件,文件在getwayworker里面

5.1 下面是start_getway.php文件,里面用到了ssl,如果没有证书请直接使用

$gateway = new Gateway("Websocket://0.0.0.0:9501");

去掉$gateway->transport = 'ssl';

!!!!一定要去配置安全组,服务器和宝塔面板都要配置,我这里使用的是9501注册地址是1236都要开启。

<?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 \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';
$context = array(// 更多ssl选项请参考手册 https://php.net/manual/zh/context.ssl.php'ssl' => array(// 请使用绝对路径'local_cert'                 => '/www/server/panel/ssl/ssl.pem', 'local_pk'                   => '/www/server/panel/ssl/ssl.key','verify_peer'               => false,// 'allow_self_signed' => true, //如果是自签名证书需要开启此选项)
);
// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("Websocket://0.0.0.0:9501",$context);
$gateway->transport = 'ssl';
// gateway名称,status方便查看
$gateway->name = 'YourAppGateway';
// // 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:1236';// 心跳间隔
$gateway->pingInterval = 55;$gateway->pingNotResponseLimit = 1;
// 心跳数据
$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();
}

5.2 更改Events.php,修改业务逻辑

<?phpuse \GatewayWorker\Lib\Gateway;class Events
{/*** 每当有客户端连接时,向该客户端发送$client_id,让客户端进行初始化.*/public static function onConnect($client_id){$resData = ['type' => 'init','client_id' => $client_id,'msg' => 'connect is success' // 初始化房间信息];Gateway::sendToClient($client_id, json_encode($resData));}/*** 该方法不用添加任何业务处理,所有的业务处理都交给thinkphp5.1的控制器Service里处理!*/public static function onMessage($client_id,$message){echo "onMessage:".$client_id.$message."\r\n";}/*** 当客户端断开连接时触发*/public static function OnClose($client_id){$msg='{"type":"onclose","client_id":"'.$client_id.'","time":"'.date('Y-m-d H:i:s').'"}';echo $msg."\r\n";}
}

5.3 配置完了,运行getwayworker。

php start.php start

5.4  测试是否成功,直接在谷歌浏览器控制台使用即可,如果没有配置ssl请使用ws:

// 证书是会检查域名的,请使用域名连接
ws = new WebSocket("wss://域名/wss");ws.onopen = function() {alert("连接成功");ws.send('tom');alert("给服务端发送一个字符串:tom");
};

5.5 mvc处理业务逻辑,tp5.1的application里自己建立控制器

server.php

<?phpnamespace app\index\controller;use GatewayClient\Gateway;
use think\Controller;
use app\common\model\ImMessage;
use app\common\model\ImMessageCatch;
use think\facade\Request;class Server
{/** 用户登录后初始化以及绑定client_id*/public function bindUid(){// 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值$param=Request::param();/*因为是一对一所以需要将前面的信息全部踢掉*/$clientArray=Gateway::getClientIdByUid($param['user_id']);if (count($clientArray)>0) {foreach ($clientArray as $k=>$v){Gateway::closeClient($v);}}// client_id与uid绑定Gateway::bindUid($param['client_id'], $param['user_id']);/*绑定成功后判断是否有未发送消息*/$this->SendCatch($param['user_id']);}//发送私聊信息public function sendMessage(){$param=Request::param();$toid=$param['toid'];$fromid=$param['fromid'];$type=$param['msg']['type'];  //信息类型$userName=$param['msg']['userinfo']['username'];$avatar=$param['msg']['userinfo']['face'];$length=0; //录音长度switch ($type) {case 'text':$name='text';$content=$param['msg']['content']['text'];break;case 'img':$name='url';$content=$param['msg']['content']['url'];break;case 'voice':$name='url';$content=$param['msg']['content']['url'];$length=$param['msg']['content']['length'];break;default:$content=$data->msg->content->text;};$id=ImMessage::create(['message_content'=>$content,'voice_length'=>$length,'type'=>$type,'from_user_id'=>$param['fromid'],'from_user_name'=>$userName,'from_user_avatar'=>$avatar,'to_user_id'=>$toid]);$res['message']['sendmethod']='user';$res['message']['type']='user';$res['message']['fromid']=$fromid;$res['message']['msg']['type']=$type;$res['message']['msg']['content'][$name]=$content;$res['message']['msg']['content']['length']=$length;$res['message']['msg']['id']=$id->id;$res['message']['msg']['time']=date('Y-m-d H:i:s',time());;$res['message']['msg']['userinfo']['uid']=$param['fromid'];$res['message']['msg']['userinfo']['username']=$userName;$res['message']['msg']['userinfo']['face']=$avatar;$res['type']='getmessage';//发送信息/*需要判断该用户是否在线*/$s=Gateway::getClientIdByUid($toid);if (count($s)==0){/*没有查到表示不在线,需要进行缓存操作*//*先将该用户添加到缓存表*/$catch=ImMessageCatch::create(['from_id'=>$fromid,'to_id'=>$toid,'message_id'=>$id->id]);if($catch->id){/*表示已经插入成功*//*执行信息推送*/$con['title']=base64_encode($userName."来信");$con['token']=base64_encode($toid);$con['sponsor_user_id']=base64_encode($fromid);$con['receiver_user_id']=base64_encode($toid);$con['content']=base64_encode(strip_tags(htmlspecialchars_decode($content)));$con['msg']=base64_encode(strip_tags(htmlspecialchars_decode($content)));$con['type']='聊天消息';$con['url']=base64_encode('/pages/tabBar/main3/main3');$url="https://push.com/push";$this->post($url,$con);}}else {Gateway::sendToUid($toid,json_encode($res));ImMessage::where('id',$id->id)->update(['status'=>1]);}}public function SendCatch($user_id){$res=ImMessageCatch::where('status',0)->where('to_id',$user_id)->select();if(!$res->isEmpty()){/*表示有人给他发消息*//*循环获取每一条信息然后给这个人发消息*/foreach ($res as $k=>$v) {$content=ImMessage::where('id',$v['message_id'])->find();/*发送缓存消息*/$this->sendCatchMessage($content,$v['id']);}}}public function sendCatchMessage($data,$catch_id){/*发送缓存数据*/$type=$data->type;  //信息类型$length=0; //录音长度switch ($type) {case 'text':$name='text';$content=$data->message_content;break;case 'img':$name='url';$content=$data->message_content;break;case 'voice':$name='url';$content=$data->message_content;$length=$data->voice_length;break;default:$content=$data->message_content;};//来源的id$fromid=$data->from_user_id;//要发送的id$toid=$data->to_user_id;$username=$data->from_user_name;$avatar=$data->from_user_avatar;$date=date('Y-m-d H:i:s',time());$res['message']['sendmethod']='user';$res['message']['type']='user';$res['message']['fromid']=$fromid;$res['message']['msg']['type']=$type;$res['message']['msg']['content'][$name]=$content;$res['message']['msg']['content']['length']=$length;$res['message']['msg']['id']=$data->id;$res['message']['msg']['time']=$date;$res['message']['msg']['userinfo']['uid']=$fromid;$res['message']['msg']['userinfo']['username']=$username;$res['message']['msg']['userinfo']['face']=$avatar;$res['type']='getmessage';//发送信息Gateway::sendToUid($toid,json_encode($res));/*发送成功修改信息状态0指的是缓存中1代表发送成功,-1代表缓存三天未上线被清除掉 */ImMessage::where('id',$data->id)->update(['status'=>1]);/*修改缓存状态*/ImMessageCatch::where('id',$catch_id)->update(['status'=>1]);echo "发送信息成功";return ;}/*获取历史聊天记录*/public function getHistoryMessage(){$data=Request::param();if(empty($data)){    return null;}$res=ImMessage::where('from_user_id', ['like', "%".$data['mid']."%"], ['like', "%".$data['toid']."%"], 'or')->where('to_user_id', ['like', "%".$data['mid']."%"], ['like', "%".$data['toid']."%"], 'or')->where('id','<',$data['message_id'])->field(['from_user_id'=>'fromid','to_user_id'=>'toid','type','id'=>'lastid','from_user_name'=>'user_name','from_user_avatar'=>'user_avatar','message_content'=>'content','voice_length'=>'length','from_unixtime(`create_time`, \'%m-%d %H:%i\') as time'])->select();if($res){return json(['code'=>200,'data'=>$res]);}else{return json(['code'=>201,'data'=>[]]);}}function post($url = '', $param = '') {if (empty($url) || empty($param)) {return false;}$postUrl = $url;$curlPost = $param;$curl = curl_init();//初始化curlcurl_setopt($curl, CURLOPT_URL,$postUrl);//抓取指定网页curl_setopt($curl, CURLOPT_HEADER, 0);//设置headercurl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上curl_setopt($curl, CURLOPT_POST, 1);//post提交方式curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);$data = curl_exec($curl);//运行curl\
//        echo 'Curl error: ' . curl_error($curl);curl_close($curl);return $data;}}

6 前端逻辑我就不讲了。

Thinkphp5.1+workerman+getway实现聊天功能相关推荐

  1. php 即时聊天 实现方法,谈谈利用workerman实现即时聊天功能的方法

    本篇文章给大家介绍一下使用workerman实现即时聊天的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 开发文档:http://doc2.workerman.net/ 下载服 ...

  2. Thinkphp5使用workerman、socket、websocket、layui、layim建立即时通讯

    在开始之前,有句话想说,曾经我以为socket会很难入门,所以为了节省时间,使用了ajax轮询的方式,最近项目不是很多,想起来优化一下曾经的项目,就准备引入socket代替ajax轮询,从开始到发出第 ...

  3. php定时爬虫,thinkphp5使用workerman定时器定时爬取站点内容的代码

    本篇文章给大家分享的内容是关于thinkphp5使用workerman定时器定时爬取某站点新闻资讯等的内容,内容很详细,有需要的朋友可以参考一下,希望可以帮助到你们. 1.首先通过 composer ...

  4. php聊天功能_php实现简单聊天功能

    搜索热词 1.创建聊天消息表,其表的字段有消息内容,发送时间和发送者的名称: CREATE TABLE `guanhui`.`message` ( `id` INT(10) NOT NULL AUTO ...

  5. Netty 4.x Netty 实现聊天功能

    Netty 实现聊天功能 Netty 是一个 Java NIO 客户端服务器框架,使用它可以快速简单地开发网络应用程序,比如服务器和客户端的协议.Netty 大大简化了网络程序的开发过程比如 TCP ...

  6. 简单java socket_基于Java Socket实现一个简易在线聊天功能(一)

    最近做了一个项目,其中有一个在线网页交流的需求,好久没写代码了,手都生疏了,于是先写demo练练手,分享到脚本之家平台,以此做个记录,方便自己和大家使用. 先给大家说下实现步骤分这样几大步: 1.使用 ...

  7. 基于PHP实现一个简单的在线聊天功能(轮询ajax )

    基于PHP实现一个简单的在线聊天功能(轮询ajax ) 一.总结 1.用的轮询ajax 二.基于PHP实现一个简单的在线聊天功能 一直很想试着做一做这个有意思的功能,感觉复杂的不是数据交互和表结构,麻 ...

  8. python实现简易聊天需要登录_python编写简易聊天室实现局域网内聊天功能

    本文实例为大家分享了python实现局域网内聊天功能的具体代码,供大家参考,具体内容如下 功能: 可以向局域网内开启接收信息功能的ip进行发送信息,我们可以写两段端口不同的代码来实现在一台电脑上与自己 ...

  9. 网络编程C/S模型怎样才能实现真正的聊天功能

    学完socket编成后,就迫不及待地写一个简单的聊天程序,好在同学面前装装逼,毕竟外行看热闹.然而在自己的电脑上运行是毫无差错,发送接收都没有问题,然而将客户端的exe文件打包后发送给其他电脑上运行时 ...

最新文章

  1. es6 中的generator函数控制流程
  2. python经典小游戏-用Python设计一个经典小游戏:猜大小
  3. 笔记本移动位置,切换网络ip后,虚拟机的mac系统无法联网解决
  4. bzoj 1801: [Ahoi2009]chess 中国象棋【dp】
  5. echarts label固定位置_ECharts+百度地图网络拓扑应用
  6. 【HDU - 5961】传递(图,思维,暴力,枚举点)
  7. git 报错:Please make sure you have the correct access rights and the repository exists
  8. 今天最好的生日礼物就是重新找到目标
  9. java http编码_java httprequest编码/解码
  10. sql azure 语法_Azure Data Studio中SQL代码段
  11. 使用VS2012新建空白解决方案
  12. 比较感兴趣的几个VC2012/VC2013特性
  13. 网站的版面设计,商业Web站点设计策略,网站CI形象设计,网页色彩的搭配
  14. 机器人动力学与控制_机器人领域值得一看的好书推荐
  15. 软件测试工作的基本流程是什么
  16. cdr宏教程_cdr软件怎么使用宏批量导出文件?
  17. android星星闪效果,使用Canvas绘制星星闪烁的效果
  18. WPS中的word如何取消英文首字母大写
  19. java错误2203win8_Win8.1提示安装Java内部错误2203的解决方法
  20. axios+springboot 报错 POST http://localhost:8080/Login 404 (Not Found)

热门文章

  1. 读书笔记——《黑客大曝光》(4/8)
  2. 如何在app store营销之实战技巧(5)
  3. SVN撤销已提交的代码
  4. 正则表达式:任意字符
  5. 基于阿里云物联网平台,用20元体验物联网开发( 自制 Arduino 环境监测仪)——实践类
  6. 1.2.1 用继电器实现1+1=2
  7. 水性胶水消泡剂采取哪些措施消除泡沫?
  8. 【代码】优化算法BGD、SGD、Momentum、Adam算法python实现
  9. asp论坛回复功能怎么实现_微信公众号整合群发图文消息功能怎么实现?
  10. iOS Certificates, Identifiers Profiles简介