ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解

本文实例讲述了ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例。分享给大家供大家参考,具体如下:

ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展(相关文章:Linux下源码包安装使用Swoole扩展)

在tp5的项目根目录下执行composer命令安装think-swoole:

composer require topthink/think-swoole

安装成功:

话不多说,直接上代码:

新建WebSocket.php控制器:

(监听端口要确认服务器放行,宝塔环境还需要添加安全组规则)

<?php

namespace app\home\controller;
use think\swoole\Server;
class WebSocket extends Server
{
  protected $host = '0.0.0.0'; //监听所有地址
  protected $port = 9501; //监听9501端口
  protected $serverType = 'socket';
  protected $option = [
    'worker_num'=> 4, //设置启动的Worker进程数
    'daemonize'	=> false, //守护进程化(上线改为true)
    'backlog'	=> 128, //Listen队列长度
    'dispatch_mode' => 2, //固定模式,保证同一个连接发来的数据只会被同一个worker处理

    //心跳检测:每60秒遍历所有连接,强制关闭10分钟内没有向服务器发送任何数据的连接
    'heartbeat_check_interval' => 60,
    'heartbeat_idle_time' => 600
  ];

  //建立连接时回调函数
  public function onOpen($server,$req)
  {
    $fd = $req->fd;//客户端标识
    $uid = $req->get['uid'];//客户端传递的用户id
    $token = $req->get['token'];//客户端传递的用户登录token

    //省略token验证逻辑......
    if (!$token) {
      $arr = array('status'=>2,'message'=>'token已过期');
      $server->push($fd, json_encode($arr));
      $server->close($fd);
      return;
    }
    //省略给用户绑定fd逻辑......
    echo "用户{$uid}建立了连接,标识为{$fd}\n";
  }

  //接收数据时回调函数
  public function onMessage($server,$frame)
  {
    $fd = $frame->fd;
    $message = $frame->data;

    //省略通过fd查询用户uid逻辑......
    $uid = 666;
    $data['uid'] = $uid;
    $data['message'] = '用户'.$uid.'发送了:'.$message;
    $data['post_time'] = date("m/d H:i",time());
    $arr = array('status'=>1,'message'=>'success','data'=>$data);

    //仅推送给当前连接用户
    //$server->push($fd, json_encode($arr));

    //推送给全部连接用户
    foreach($server->connections as $fd) {
      $server->push($fd, json_encode($arr));
    }
  }

  //连接关闭时回调函数
  public function onClose($server,$fd)
  {
    echo "标识{$fd}关闭了连接\n";
  }
}

前端演示页面:

(省略控制器判断登录状态、分配数据逻辑......)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>Chat</title>
<link rel="stylesheet" type="text/css" href="/static/liaotian/chat.css" rel="external nofollow" />
<script src="/static/liaotian/js/jquery.min.js"></script>
<script src="/static/liaotian/js/flexible.js"></script>
</head>
<body>
  <header class="header">
    <a class="back" href="javascript:history.back()" rel="external nofollow" ></a>
    <h5 class="tit">在线聊天</h5>
    <a href=""><div class=" rel="external nofollow" right">退出</div></a>
  </header>

  <!-- 聊天内容 start-->
	<div class="message"> </div>
  <!-- 聊天内容 end-->

  <!-- 底部 start-->
  <div class="footer">
    <img id="setbtn" src="/static/liaotian/images/hua.png" alt="" />
    <img src="/static/liaotian/images/xiaolian.png" alt="" />
    <input type="text" id="msg" value="" maxlength="300">
    <p style="background: rgb(17, 79, 142);" id="sendBtn">发送</p>
  </div>
  <!-- 底部 end-->
</body>
</html>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/layer/3.1.0/layer.js"></script>
<script type="text/javascript">
$(function () {
  var uid = 666;//当前用户id
  var token = 'abcdefg';//用户token

  //判断浏览器是否支持WebSocket
  var supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in window;
  if (supportsWebSockets) {
    //建立WebSocket连接(ip地址换成自己主机ip)
    var ws = new WebSocket("ws://127.0.0.1:9501?uid="+uid+"&token="+token);
    ws.onopen = function () {
      layer.msg('服务器连接成功',{shade:0.1,icon:1,time:600});
    };
    ws.onerror = function () {
      layer.msg('服务器连接失败',{shade:0.1,icon:2,time:600});
    };
    ws.onmessage = function (evt) {
      var data = $.parseJSON(evt.data);
      //错误提示
      if(data.status != 1){
        layer.alert(data.message,{icon:2});
        return;
      }
      //消息返回
      if (data.status==1 && data.data.message!='') {
        var html = "";
        if (data.data.uid == uid) {
          html += "<div style='word-break:break-all' class=\"show\"><div class=\"time\">"+data.data.post_time+"</div><div class=\"msg\"><img src=\""+data.data.head_img+"\" alt=\"\" /><p><i clas=\"msg_input\"></i>"+data.data.message+"</p></div></div>";
        }else{
          html += "<div style='word-break:break-all' class=\"send\"><div class=\"time\">"+data.data.post_time+"</div><div class=\"msg\"><img src=\""+data.data.head_img+"\" alt=\"\" /><p><i clas=\"msg_input\"></i>"+data.data.message+"</p></div></div>";
        }
      }
      $(".message").append(html);
      setTimeout(function () {
        ($('.message').children("div:last-child")[0]).scrollIntoView();//向上滚动
      },100);
    };
    ws.onclose = function (res) {

    };
    //按钮发送
    $("#sendBtn").click(function () {
      var contents = $("#msg").val().trim();
      if(contents == null || contents == ""){
        layer.msg('内容为空',{shade:0.1,icon:2,time:600});
        return false;
      }else{
      	ws.send(contents);
      	$("#msg").val("");
      }
    });
    //回车发送
    $("#msg").keydown(function (evel) {
      var that = $(this);
      if (evel.keyCode == 13) {
        evel.cancelBubble = true;
        evel.preventDefault();
        evel.stopPropagation();
        var contents = that.val().trim();
        if(contents == null || contents == ""){
          layer.msg('内容为空',{shade:0.1,icon:2,time:600});
          return false;
        }else{
          ws.send(contents);
          that.val("");
        }
      }
    });
  }else{
    layer.alert("您的浏览器不支持 WebSocket!");
  }
});
</script>

服务器移到项目根目录开启服务:

php public/index.php Websocket/start

(这里的路径,是因为我绑定了home模块为默认模块,tp5默认情况是:php public/index.php index/Websocket/start

开启成功,查看端口已经被监听:

lsof -i:9501

演示效果如下:

服务器监听如下:

用户每刷新重连一次,fd标识都会改变。

更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《Zend FrameWork框架入门教程》及《PHP模板技术总结》。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

(0)

相关推荐

  • 使用swoole扩展php websocket示例

    复制代码 代码如下: <?phpdefine('DEBUG', 'on');define("WEBPATH", str_replace("\\","/", __DIR__));require __DIR__ . '/../libs/lib_config.php'; class WebSocket extends Swoole\Network\Protocol\WebSocket{    /**     * 下线时,通知所有人     */ 

  • Swoole实现异步投递task任务案例详解

    本文实例讲述了Swoole实现异步投递task任务案例.分享给大家供大家参考,具体如下: [使用场景] Swolle的task模块可以用来做一些异步的慢速任务.耗时场景.如webim中发广播,发送邮件等,把这些任务丢给task进程之后,worker进程可以继续处理新的数据请求,任务完成后会异步通知worker进程告诉它此任务已经完成.此外利用task还可以实现PHP的数据库连接池,异步队列等. [使用须知] 必须设置Task进程数: task_worker_num 投递一个异步任务到task_w

  • Linux下源码包安装Swoole及基本使用操作图文详解

    本文实例讲述了Linux下源码包安装Swoole及基本使用操作.分享给大家供大家参考,具体如下: 下载Swoole PECL扩展源码包:http://pecl.php.net/package/swoole 关于PHP版本依赖选择: 下载好放到/usr/local/src下,解压缩: tar -zxvf swoole-2.2.0.tgz 准备扩展安装编译环境: phpize 查看php-config位置: find / -name php-config 配置:(--with-php-config=

  • PHP+swoole实现简单多人在线聊天群发

    由于本文的能力有限,有好多聊天逻辑的细节没有实现,只实现了群发,具体代码如下所示: php代码: $serv = new swoole_websocket_server("127.0.0.1",3999); //服务的基本设置 $serv->set(array( 'worker_num' => 2, 'reactor_num'=>8, 'task_worker_num'=>1, 'dispatch_mode' => 2, 'debug_mode'=>

  • 详解thinkphp5+swoole实现异步邮件群发(SMTP方式)

    本文介绍了thinkphp5+swoole实现异步邮件群发(SMTP方式),分享给大家,具体如下: 1.环境说明 阿里云centos7 thinkphp5.0.11 swoole2.0.8 2.tp实现邮件发送 在项目下建立如下的文件目录: 其中SendMail.php是我们实际调用的发送邮件的文件.以下是主要代码: namespace app\library\utils\mail; use app\library\utils\mail\PhpMailer; use app\library\ut

  • php安装swoole扩展的方法

    本文实例讲述了php安装swoole扩展的方法.分享给大家供大家参考.具体如下: 我本机是OS X,想要安装swoole体验一下,于是: 复制代码 代码如下: andy@AndyMacBookPro:/usr/local/webdata/github$ cd swoole-src/ andy@AndyMacBookPro:/usr/local/webdata/github/swoole-src$ git pull Already up-to-date. andy@AndyMacBookPro:/

  • PHP的swoole扩展安装方法详细教程

    Swoole支持PHP 5.3.10以上版本,所以安装Swoole之前请先安装PHP 5.3.10以上版本,现在来介绍Windows下PHP安装配置方法. 软件版本:php-5.3.1-Win32-VC6-x86.zip 这个不需要额外的安装.net的库,所以就用这个了.可以使用其他的. 1.PHP安装 使用绿色方式,下载Zip文件解压. 2.配置 在解压的根目录下找到php.ini-development,是用于开发环境的配置文件:还有一个php.ini-production,这个是用于生产环

  • php异步多线程swoole用法实例

    本文实例讲述了php异步多线程swoole用法.分享给大家供大家参考.具体分析如下: swoole重新定义PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务,下面的实例就可以证实这一功能. 一般来说,Swoole提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. swoole以前听过, 拿来做游戏服务器简直是神器-今天稍微的感受了一下,  在 ubuntu 下搭建了

  • ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解

    本文实例讲述了ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例.分享给大家供大家参考,具体如下: ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展(相关文章:Linux下源码包安装使用Swoole扩展) 在tp5的项目根目录下执行composer命令安装think-swoole: composer require topthink/think-swoole 安装成功: 话不多说

  • Laravel5.0+框架邮件发送功能实现方法图文与实例详解

    本文实例讲述了Laravel5.0+框架邮件发送功能实现方法.分享给大家供大家参考,具体如下: I. 背景 近期在接触传说中最优雅的 PHP 框架--Laravel,学习了一下邮件发送功能,在此分享一下 测试环境:Laravel 5.2.45,Laravel 5.5 使用协议:SMTP 邮件传输协议 对于 ThinkPHP 框架框架的邮件发送可参考文章 ThinkPHP 框架下邮件发送功能 II. 功能开发过程 此处以 网易(163.com)邮箱为例. 一.前期准备 (1).首先对 SMTP 的

  • Django开发的简易留言板案例详解

    本文实例讲述了Django开发的简易留言板.分享给大家供大家参考,具体如下: Django在线留言板小练习 环境 ubuntu16.04 + python3 + django1.11 1.创建项目 django-admin.py startproject message 进入项目message 2.创建APP python manager.py startapp guestbook 项目结构 . ├── guestbook │   ├── admin.py │   ├── apps.py │  

  • thinkPHP5.0框架开发规范简介

    本文实例讲述了thinkPHP5.0框架开发规范.分享给大家供大家参考,具体如下: 命名规范 ThinkPHP5遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范: 目录和文件 目录不强制规范,驼峰及小写+下划线模式均支持: 类库.函数文件统一以.php为后缀: 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致: 类名和类文件名保持一致,统一采用驼峰法命名(首字母大写): 函数和类.属性命名 类的命名采用驼峰法,并且首字母大写,例如 User.UserType,

  • thinkPHP5.0框架引入Traits功能实例分析

    本文实例讲述了thinkPHP5.0框架引入Traits功能.分享给大家供大家参考,具体如下: ThinkPHP 5.0开始采用trait功能(PHP5.4+)来作为一种扩展机制,可以方便的实现一个类库的多继承问题. Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集.Traits和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题. 但由于

  • thinkPHP5.0框架API优化后的友好性分析

    本文实例讲述了thinkPHP5.0框架API优化后的友好性.分享给大家供大家参考,具体如下: 新版ThinkPHP针对API开发做了很多的优化,并且不依赖原来的API模式扩展. 数据输出 新版的控制器输出采用Response类统一处理,而不是直接在控制器中进行输出,通过设置default_return_type或者动态设置不同类型的Response输出就可以自动进行数据转换处理,一般来说,你只需要在控制器中返回字符串或者数组即可,例如如果我们配置: 'default_return_type'=

  • ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】

    本文实例讲述了ThinkPHP5.0框架验证码功能实现方法.分享给大家供大家参考,具体如下: 背景 ThinkPHP5.0 已经出现很久了,最近有所接触,下面介绍一下常用的第三方验证码功能的使用. ♜ 功能开发 1).引入第三方扩展包 进行 TP5 的开发,Composer 的使用会成为重要技能,以 windows 为例子,输入命令: composer require topthink/think-captcha 完成上述操作,会在以下目录中出现 captcha 的扩展包 ..\vendor\t

  • thinkPHP5.0框架安装教程

    本文实例讲述了thinkPHP5.0框架安装方法.分享给大家供大家参考,具体如下: ThinkPHP5的环境要求如下: PHP >= 5.4.0 PDO PHP Extension MBstring PHP Extension CURL PHP Extension 严格来说,ThinkPHP无需安装过程,这里所说的安装其实就是把ThinkPHP框架放入WEB运行环境(前提是你的WEB运行环境已经OK),可以通过两种方式获取和安装ThinkPHP. 一.下载ThinkPHP安装 获取ThinkPH

  • thinkPHP5.0框架命名空间详解

    本文实例讲述了thinkPHP5.0框架命名空间.分享给大家供大家参考,具体如下: 命名空间 ThinkPHP采用命名空间方式定义和自动加载类库文件,有效的解决了多模块和Composer类库之间的命名空间冲突问题,并且实现了更加高效的类库自动加载机制. 如果不清楚命名空间的基本概念,可以参考PHP手册:PHP命名空间 特别注意的是,如果你需要调用PHP内置的类库,或者第三方没有使用命名空间的类库,记得在实例化类库的时候加上 \,例如: // 错误的用法 $class = new stdClass

随机推荐