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. 致远OA_0day批量植Cknife马一步到位

    最近各位师傅都在刷这个嘛,原本的exp是上传一个test123456.jsp的命令执行的马子,不过我在试的时候发现替换成C刀一句话出错,原因未知,并且test123456.jsp如果存在的话用原来ex ...

  2. ES6入门之变量的解构赋值(二)

    前言 在上一章 ES6入门之let和const命令中我们对ES6的相关语法已经有了初步了解,上一章中我们主要学习了三大部分的内容,let命令的使用,块级作用域,const命令的使用,那么从本篇博客将进 ...

  3. win10系统plsql卡顿、菜单闪烁解决办法

    右键快捷方式--属性--兼容性: 设置为以win7模式运行,以管理员模式运行.如图:

  4. [Abp vNext 源码分析] - 12. 后台作业与后台工作者

    一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 24 日晚 更新日期:暂无 ABP vNext 提供了后台工作者和后台作业的支持,基本实现与原 ...

  5. java web项目下的lib和build path 中jar包问题解惑

    一.build path&WEB-INFO/lib介绍 build path:可以说是引用: WEB-INFO/lib:可以说是固定在一个地方: eclipse编译项目的时候是根据build ...

  6. mac安装MongoDB教程

    目录 介绍 下载安装 方法1 方法2 配置 配置PATH 创建log和data目录 启动 关闭 介绍 基于分布式文件存储的数据库,使用C++编写. 应用最广泛的非关系型数据库(NoSQL). NoSQ ...

  7. 使用Jersey构建图片服务器

    使用Jersey构建图片服务器 前台页面代码 <form id="jvForm" action="add.do" method="post&qu ...

  8. 百万年薪python之路 -- 异常处理

    异常处理 1.错误的分类: 1.语法错误:(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) #语法错误示范一 if #语法错误示范二 def test: pass #语法错 ...

  9. 百万年薪python之路 -- 基础数据类型的补充练习

    1.看代码写结果 v1 = [1,2,3,4,5] v2 = [v1,v1,v1] v1.append(6) print(v1) print(v2) [1,2,3,4,5,6] [[1,2,3,4,5 ...

  10. 从零开始把项目发布到Nuget仓库中心

    从零开始把项目发布到Nuget仓库中心 我的项目地址 https://github.com/Ants-double/dasuan ### 前期准备 下载并注册nuget帐号 下载地址 https:// ...