您的位置:首页 > 编程学习 > > 正文

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

更多 时间:2022-03-31 00:11:51 类别:编程学习 浏览量:957

thinkphp接口开发实例

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

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

thinkphp使用swoole需要安装 think-swoole composer包,前提系统已经安装好了swoole pecl 拓展(相关文章:linux下源码包安装使用swoole扩展)

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

  • ?
  • 1
  • composer require topthink/think-swoole
  •  
  • thinkphp接口开发实例(ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解)

    安装成功:

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

    话不多说,直接上代码:

    新建websocket.php控制器:

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

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • <?php
  •  
  • namespace apphomecontroller;
  • use thinkswooleserver;
  • 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} ";
  •   }
  •  
  •   //接收数据时回调函数
  •   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}关闭了连接 ";
  •   }
  • }
  • 前端演示页面:

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

    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" rel="external nofollow" /> 
    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()" rel="external nofollow" ></a> 
    15.     <h5 class="tit">在线聊天</h5> 
    16.     <a href=""><li class=" rel="external nofollow" right">退出</li></a> 
    17.   </header> 
    18.  
    19.   <!-- 聊天内容 start--> 
    20.     <li class="message"> </li> 
    21.   <!-- 聊天内容 end--> 
    22.  
    23.   <!-- 底部 start--> 
    24.   <li class="footer"
    25.     <img id="setbtn" src="/static/liaotian/images/hua.jpg" alt="thinkphp接口开发实例(ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解)" border="0" /> alt="" /> 
    26.     <img src="/static/liaotian/images/xiaolian.jpg" alt="thinkphp接口开发实例(ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解)" border="0" /> alt="" /> 
    27.     <input type="text" id="msg" value="" maxlength="300"
    28.     <p style="background: rgb(17, 79, 142);" id="sendbtn">发送</p> 
    29.   </li> 
    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 += "<li style='word-break:break-all' class="show"><li class="time">"+data.data.post_time+"</li><li class="msg"><img src=""+data.data.head_img+"" alt="" /><p><i clas="msg_input"></i>"+data.data.message+"</p></li></li>"
    63.         }else
    64.           html += "<li style='word-break:break-all' class="send"><li class="time">"+data.data.post_time+"</li><li class="msg"><img src=""+data.data.head_img+"" alt="" /><p><i clas="msg_input"></i>"+data.data.message+"</p></li></li>"
    65.         } 
    66.       } 
    67.       $(".message").append(html); 
    68.       settimeout(function () { 
    69.         ($('.message').children("li: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
  •  
  • thinkphp接口开发实例(ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解)

     演示效果如下:

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

    服务器监听如下:

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

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

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

    原文链接:https://blog.csdn.net/msllws/article/details/84405127

    您可能感兴趣