ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展*

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

  1. composer require topthink/think-swoole

话不多说,直接上代码:

新建WebSocket.php控制器

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

  1. <?php
  2.  
  3. namespace app\home\controller;
  4. use think\swoole\Server;
  5. class WebSocket extends Server
  6. {
  7. protected $host = '0.0.0.0'; //监听所有地址
  8. protected $port = 9501; //监听9501端口
  9. protected $serverType = 'socket';
  10. protected $option = [
  11. 'worker_num'=> 4, //设置启动的Worker进程数
  12. 'daemonize' => false, //守护进程化(上线改为true)
  13. 'backlog' => 128, //Listen队列长度
  14. 'dispatch_mode' => 2, //固定模式,保证同一个连接发来的数据只会被同一个worker处理
  15.  
  16. //心跳检测:每60秒遍历所有连接,强制关闭10分钟内没有向服务器发送任何数据的连接
  17. 'heartbeat_check_interval' => 60,
  18. 'heartbeat_idle_time' => 600
  19. ];
  20.  
  21. //建立连接时回调函数
  22. public function onOpen($server,$req)
  23. {
  24. $fd = $req->fd;//客户端标识
  25. $uid = $req->get['uid'];//客户端传递的用户id
  26. $token = $req->get['token'];//客户端传递的用户登录token
  27.  
  28. //省略token验证逻辑......
  29. if (!$token) {
  30. $arr = array('status'=>2,'message'=>'token已过期');
  31. $server->push($fd, json_encode($arr));
  32. $server->close($fd);
  33. return;
  34. }
  35. //省略给用户绑定fd逻辑......
  36. echo "用户{$uid}建立了连接,标识为{$fd}\n";
  37. }
  38.  
  39. //接收数据时回调函数
  40. public function onMessage($server,$frame)
  41. {
  42. $fd = $frame->fd;
  43. $message = $frame->data;
  44.  
  45. //省略通过fd查询用户uid逻辑......
  46. $uid = 666;
  47. $data['uid'] = $uid;
  48. $data['message'] = '用户'.$uid.'发送了:'.$message;
  49. $data['post_time'] = date("m/d H:i",time());
  50. $arr = array('status'=>1,'message'=>'success','data'=>$data);
  51.  
  52. //仅推送给当前连接用户
  53. //$server->push($fd, json_encode($arr));
  54.  
  55. //推送给全部连接用户
  56. foreach($server->connections as $fd) {
  57. $server->push($fd, json_encode($arr));
  58. }
  59. }
  60.  
  61. //连接关闭时回调函数
  62. public function onClose($server,$fd)
  63. {
  64. echo "标识{$fd}关闭了连接\n";
  65. }
  66. }

前端演示页面:

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  6. <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  7. <title>Chat</title>
  8. <link rel="stylesheet" type="text/css" href="/static/liaotian/chat.css" />
  9. <script src="/static/liaotian/js/jquery.min.js"></script>
  10. <script src="/static/liaotian/js/flexible.js"></script>
  11. </head>
  12. <body>
  13. <header class="header">
  14. <a class="back" href="javascript:history.back()"></a>
  15. <h5 class="tit">在线聊天</h5>
  16. <a href=""><div class="right">退出</div></a>
  17. </header>
  18.  
  19. <!-- 聊天内容 start-->
  20. <div class="message"> </div>
  21. <!-- 聊天内容 end-->
  22.  
  23. <!-- 底部 start-->
  24. <div class="footer">
  25. <img id="setbtn" src="/static/liaotian/images/hua.png" alt="" />
  26. <img src="/static/liaotian/images/xiaolian.png" alt="" />
  27. <input type="text" id="msg" value="" maxlength="300">
  28. <p style="background: rgb(17, 79, 142);" id="sendBtn">发送</p>
  29. </div>
  30. <!-- 底部 end-->
  31. </body>
  32. </html>
  33. <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  34. <script src="https://cdn.bootcss.com/layer/3.1.0/layer.js"></script>
  35. <script type="text/javascript">
  36. $(function () {
  37. var uid = 666;//当前用户id
  38. var token = 'abcdefg';//用户token
  39.  
  40. //判断浏览器是否支持WebSocket
  41. var supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in window;
  42. if (supportsWebSockets) {
  43. //建立WebSocket连接(ip地址换成自己主机ip)
  44. var ws = new WebSocket("ws://127.0.0.1:9501?uid="+uid+"&token="+token);
  45. ws.onopen = function () {
  46. layer.msg('服务器连接成功',{shade:0.1,icon:1,time:600});
  47. };
  48. ws.onerror = function () {
  49. layer.msg('服务器连接失败',{shade:0.1,icon:2,time:600});
  50. };
  51. ws.onmessage = function (evt) {
  52. var data = $.parseJSON(evt.data);
  53. //错误提示
  54. if(data.status != 1){
  55. layer.alert(data.message,{icon:2});
  56. return;
  57. }
  58. //消息返回
  59. if (data.status==1 && data.data.message!='') {
  60. var html = "";
  61. if (data.data.uid == uid) {
  62. 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>";
  63. }else{
  64. 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>";
  65. }
  66. }
  67. $(".message").append(html);
  68. setTimeout(function () {
  69. ($('.message').children("div:last-child")[0]).scrollIntoView();//向上滚动
  70. },100);
  71. };
  72. ws.onclose = function (res) {
  73.  
  74. };
  75. //按钮发送
  76. $("#sendBtn").click(function () {
  77. var contents = $("#msg").val().trim();
  78. if(contents == null || contents == ""){
  79. layer.msg('内容为空',{shade:0.1,icon:2,time:600});
  80. return false;
  81. }else{
  82. ws.send(contents);
  83. $("#msg").val("");
  84. }
  85. });
  86. //回车发送
  87. $("#msg").keydown(function (evel) {
  88. var that = $(this);
  89. if (evel.keyCode == 13) {
  90. evel.cancelBubble = true;
  91. evel.preventDefault();
  92. evel.stopPropagation();
  93. var contents = that.val().trim();
  94. if(contents == null || contents == ""){
  95. layer.msg('内容为空',{shade:0.1,icon:2,time:600});
  96. return false;
  97. }else{
  98. ws.send(contents);
  99. that.val("");
  100. }
  101. }
  102. });
  103. }else{
  104. layer.alert("您的浏览器不支持 WebSocket!");
  105. }
  106. });
  107. </script>

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

  1. php public/index.php Websocket/start

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

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

  1. lsof -i:9501

phper在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的(点击→)我的官方群677079770

Swoole跟thinkphp5结合开发WebSocket在线聊天通讯系统的更多相关文章

  1. FastAPI(七十)实战开发《在线课程学习系统》接口开发--留言功能开发

    在之前的文章:FastAPI(六十九)实战开发<在线课程学习系统>接口开发--修改密码,这次分享留言功能开发 我们能梳理下对应的逻辑 1.校验用户是否登录 2.校验留言的用户是否存在 3. ...

  2. 基于java开发的在线题库系统tamguo

    简介 探果网(简称tamguo)是基于java开发的在线题库系统,包括 在线访问 后台运营 会员中心 书籍中心 管理员账号:system 密码:123456 因为线上数据和测试数据没有做到隔离,作者已 ...

  3. FastAPI(六十三)实战开发《在线课程学习系统》梳理系统需要接口

    针对上一篇FastAPI(六十二)实战开发<在线课程学习系统>需求分析需求的功能,我们对需要的接口进行梳理,大概的规划出来现有的接口,作为我们第一版的接口的设计出版,然后我们根据设计的接口 ...

  4. FastAPI(七十四)实战开发《在线课程学习系统》接口开发-- 删除留言

    之前文章FastAPI(七十三)实战开发<在线课程学习系统>接口开发-- 回复留言,那么我们这次分享删除留言接口的开发 可以对留言进行删除,这里的删除,我们使用的是逻辑的删除,不是物理删除 ...

  5. FastAPI(七十三)实战开发《在线课程学习系统》接口开发-- 回复留言

    之前文章分享FastAPI(七十二)实战开发<在线课程学习系统>接口开发-- 留言列表开发,这次我们分享如何回复留言 按照惯例,我们还是去分析这里面的逻辑. 1.判断用户是否登录 2.用户 ...

  6. FastAPI(七十二)实战开发《在线课程学习系统》接口开发-- 留言列表开发

    之前我们分享了FastAPI(七十一)实战开发<在线课程学习系统>接口开发-- 查看留言,这次我们分享留言列表开发. 列表获取,也需要登录,根据登录用户来获取对应的留言.逻辑梳理如下. 1 ...

  7. FastAPI(七十一)实战开发《在线课程学习系统》接口开发-- 查看留言

    之前FastAPI(七十)实战开发<在线课程学习系统>接口开发--留言功能开发分享了留言开发,这次我们分享查看留言 梳理这里的逻辑,这个接口要依赖登录. 1.判断用户是否登录 2.判断对应 ...

  8. FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码

    之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...

  9. FastAPI(六十八)实战开发《在线课程学习系统》接口开发--用户 个人信息接口开发

    在之前的文章:FastAPI(六十七)实战开发<在线课程学习系统>接口开发--用户登陆接口开发,今天实战:用户 个人信息接口开发. 在开发个人信息接口的时候,我们要注意了,因为我们不一样的 ...

随机推荐

  1. 使用Xming显示Oracle Linux图形界面

    如果你在尝试各种官方说明文档中的方法之后,xclock仍然无法远程显示. 系统 Win10 - Oracle Linux 7.5 Xming的文档以及网上教程都说的是Xming相关的配置 但是,要显示 ...

  2. “零基础”如何快速掌握web前端核心技术?

    前端开发要学的知识内容涉及的会很宽泛,虽然说主要是HTML.CSS和JavaScript这些基础知识点,今天想强调一下,学前端开发除了要学这些基础知识外,学员还要在这之上进行延伸和深入的去学,而且互联 ...

  3. [HDU5001]Walk

    Problem Description I used to think I could be anything, but now I know that I couldn't do anything. ...

  4. 利用window10的Linux子系统实现docker的安装使用

    先参照 此博客 点这里 我在执行 apt installdocker.io 命令时,不能正确的安装 docker client 所以我找了下面的命令,然后执行 docker version 成功了 辅 ...

  5. python日记:用pytorch搭建一个简单的神经网络

    最近在学习pytorch框架,给大家分享一个最最最最基本的用pytorch搭建神经网络并且训练的方法.本人是第一次写这种分享文章,希望对初学pytorch的朋友有所帮助! 一.任务 首先说下我们要搭建 ...

  6. Python 爬取豆瓣TOP250实战

    学习爬虫之路,必经的一个小项目就是爬取豆瓣的TOP250了,首先我们进入TOP250的界面看看. 可以看到每部电影都有比较全面的简介.其中包括电影名.导演.评分等. 接下来,我们就爬取这些数据,并将这 ...

  7. Vulnhub靶场渗透练习(三) bulldog

    拿到靶场后先对ip进行扫描 获取ip  和端口 针对项目路径爆破 获取两个有用文件 http://192.168.18.144/dev/ dev,admin 更具dev 发现他们用到框架和语言 找到一 ...

  8. spring security原理-学习笔记2-核心组件

    核心组件 AuthenticationManager,ProviderManager和AuthenticationProvider AuthenticationManager只是一个接口,实际中是如何 ...

  9. 二叉树的查找(前序、中序、后序、层序遍历)--biaobiao88

    建立一棵含有n个结点的二叉树,采用二叉链表存储: 输出前序.中序.后序..层序遍历该二叉树的遍历结果. 定义二叉树的数据类型——二叉树结点结构体BiNode.建立二叉链表可以采用扩展二叉树的一个遍历序 ...

  10. canvas模拟中国铁路运行图

    原理说明 1.在知道canvas画布尺寸的情况下,需要将地理经纬度信息转换为canvas画布x,y坐标,因为中国地图地理经纬度坐标取值范围为73.33-135.05(经度)37-50(维度),所以第一 ...