Swoole跟thinkphp5结合开发WebSocket在线聊天通讯系统
ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展*
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" />
- <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()"></a>
- <h5 class="tit">在线聊天</h5>
- <a href=""><div class="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
phper在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的(点击→)我的官方群677079770
Swoole跟thinkphp5结合开发WebSocket在线聊天通讯系统的更多相关文章
- FastAPI(七十)实战开发《在线课程学习系统》接口开发--留言功能开发
在之前的文章:FastAPI(六十九)实战开发<在线课程学习系统>接口开发--修改密码,这次分享留言功能开发 我们能梳理下对应的逻辑 1.校验用户是否登录 2.校验留言的用户是否存在 3. ...
- 基于java开发的在线题库系统tamguo
简介 探果网(简称tamguo)是基于java开发的在线题库系统,包括 在线访问 后台运营 会员中心 书籍中心 管理员账号:system 密码:123456 因为线上数据和测试数据没有做到隔离,作者已 ...
- FastAPI(六十三)实战开发《在线课程学习系统》梳理系统需要接口
针对上一篇FastAPI(六十二)实战开发<在线课程学习系统>需求分析需求的功能,我们对需要的接口进行梳理,大概的规划出来现有的接口,作为我们第一版的接口的设计出版,然后我们根据设计的接口 ...
- FastAPI(七十四)实战开发《在线课程学习系统》接口开发-- 删除留言
之前文章FastAPI(七十三)实战开发<在线课程学习系统>接口开发-- 回复留言,那么我们这次分享删除留言接口的开发 可以对留言进行删除,这里的删除,我们使用的是逻辑的删除,不是物理删除 ...
- FastAPI(七十三)实战开发《在线课程学习系统》接口开发-- 回复留言
之前文章分享FastAPI(七十二)实战开发<在线课程学习系统>接口开发-- 留言列表开发,这次我们分享如何回复留言 按照惯例,我们还是去分析这里面的逻辑. 1.判断用户是否登录 2.用户 ...
- FastAPI(七十二)实战开发《在线课程学习系统》接口开发-- 留言列表开发
之前我们分享了FastAPI(七十一)实战开发<在线课程学习系统>接口开发-- 查看留言,这次我们分享留言列表开发. 列表获取,也需要登录,根据登录用户来获取对应的留言.逻辑梳理如下. 1 ...
- FastAPI(七十一)实战开发《在线课程学习系统》接口开发-- 查看留言
之前FastAPI(七十)实战开发<在线课程学习系统>接口开发--留言功能开发分享了留言开发,这次我们分享查看留言 梳理这里的逻辑,这个接口要依赖登录. 1.判断用户是否登录 2.判断对应 ...
- FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码
之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...
- FastAPI(六十八)实战开发《在线课程学习系统》接口开发--用户 个人信息接口开发
在之前的文章:FastAPI(六十七)实战开发<在线课程学习系统>接口开发--用户登陆接口开发,今天实战:用户 个人信息接口开发. 在开发个人信息接口的时候,我们要注意了,因为我们不一样的 ...
随机推荐
- 致远OA_0day批量植Cknife马一步到位
最近各位师傅都在刷这个嘛,原本的exp是上传一个test123456.jsp的命令执行的马子,不过我在试的时候发现替换成C刀一句话出错,原因未知,并且test123456.jsp如果存在的话用原来ex ...
- ES6入门之变量的解构赋值(二)
前言 在上一章 ES6入门之let和const命令中我们对ES6的相关语法已经有了初步了解,上一章中我们主要学习了三大部分的内容,let命令的使用,块级作用域,const命令的使用,那么从本篇博客将进 ...
- win10系统plsql卡顿、菜单闪烁解决办法
右键快捷方式--属性--兼容性: 设置为以win7模式运行,以管理员模式运行.如图:
- [Abp vNext 源码分析] - 12. 后台作业与后台工作者
一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 24 日晚 更新日期:暂无 ABP vNext 提供了后台工作者和后台作业的支持,基本实现与原 ...
- java web项目下的lib和build path 中jar包问题解惑
一.build path&WEB-INFO/lib介绍 build path:可以说是引用: WEB-INFO/lib:可以说是固定在一个地方: eclipse编译项目的时候是根据build ...
- mac安装MongoDB教程
目录 介绍 下载安装 方法1 方法2 配置 配置PATH 创建log和data目录 启动 关闭 介绍 基于分布式文件存储的数据库,使用C++编写. 应用最广泛的非关系型数据库(NoSQL). NoSQ ...
- 使用Jersey构建图片服务器
使用Jersey构建图片服务器 前台页面代码 <form id="jvForm" action="add.do" method="post&qu ...
- 百万年薪python之路 -- 异常处理
异常处理 1.错误的分类: 1.语法错误:(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) #语法错误示范一 if #语法错误示范二 def test: pass #语法错 ...
- 百万年薪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 ...
- 从零开始把项目发布到Nuget仓库中心
从零开始把项目发布到Nuget仓库中心 我的项目地址 https://github.com/Ants-double/dasuan ### 前期准备 下载并注册nuget帐号 下载地址 https:// ...