安装swoole

pecl install swoole
修改PHP配置文件php.ini加入
extension=swoole.so

有可能不需要人工去加,安装时自动加入进来了,

查看swoole扩展是否安装好

/usr/local/php/bin/php -m

配制列表里面如果有swoole的话,恭喜你安装并配置swoole成功。

在index.php同级目录下面新新建ws.php文件,文件内容以下

<?php
class Ws {
CONST HOST = "0.0.0.0";
CONST PORT = 9501; public $ws = null;
public function __construct() {
$this->ws = new swoole_websocket_server(self::HOST, self::PORT); $this->ws->set(
[
'worker_num' => 4,//打开的进程数
'daemonize'=>0,//1守护进程,在后台一直运行
]
); //websocket继承于http_service,所以拥有http_service服务器的所有函数 //http_service函数,
$this->ws->on("start", [$this, 'onStart']);
$this->ws->on("workerstart", [$this, 'onWorkerStart']);//此事件在Worker进程/Task进程启动时发生。
$this->ws->on("request", [$this, 'onRequest']);
$this->ws->on("task", [$this, 'onTask']);
$this->ws->on("finish", [$this, 'onFinish']); //websocket函数
$this->ws->on("open", [$this, 'onOpen']);
$this->ws->on("message", [$this, 'onMessage']);
$this->ws->on("close", [$this, 'onClose']);
$this->ws->start();//开启
} /**
* @param $server
*/
public function onStart($server) {
swoole_set_process_name("websocket");//修改进程名称,非必要
}
/**
* @param $server
* @param $worker_id
*/
public function onWorkerStart($server, $worker_id) { //swoole是cli运行,执行地址path会无法正确找到,所以把base.php里面定义的常量提出来,设置为假,
//注意:记住把源代码base.php里面的define('IS_CLI',false)代码去掉(常量不能重复定义),在index.php里面加入代码:define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
define('IS_CLI',false);// //当进程运行时,把框架代码加载进来
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架里面的文件
require __DIR__ . '/../thinkphp/base.php';
} /**
* request回调
* 当请求过来时,会调用此方法,调用thinkphp真正的执行逻辑
* @param $request
* @param $response
*/
public function onRequest($request, $response) {
//因为这些全局变量会在进程的内存里面不变,所有每次请求到来先清空值。 if($request->server['request_uri'] == '/favicon.ico') {
$response->status(404);
$response->end();
return ;
}
$_SERVER = [];
if(isset($request->server)) {
foreach($request->server as $k => $v) {
$_SERVER[strtoupper($k)] = $v;
}
}
if(isset($request->header)) {
foreach($request->header as $k => $v) {
$_SERVER[strtoupper($k)] = $v;
}
} $_GET = [];
if(isset($request->get)) {
foreach($request->get as $k => $v) {
$_GET[$k] = $v;
}
}
$_FILES = [];
if(isset($request->files)) {
foreach($request->files as $k => $v) {
$_FILES[$k] = $v;
}
}
$_POST = [];
if(isset($request->post)) {
foreach($request->post as $k => $v) {
$_POST[$k] = $v;
}
} $_POST['http_server'] = $this->ws;//把对像传过去 ob_start();
try { // 执行应用并响应
think\App::run()->send();
}catch (\Exception $e) {
// todo
echo $e->getMessage();
} $res = ob_get_contents();
ob_end_clean();
$response->end($res);
} /**
* 监听ws连接事件
* @param $ws
* @param $request
*/
public function onOpen($ws, $request) {
$ws->push($request->fd, "hello, welcome\n");//发送消息给客户端 /*
与thinkphp框架结合
think\App::run();//如果不执行这行代码,框架里面很多功能用不了 //执类指定类里面的指定方法
$obj=new \app\index\controller\Login();
$obj->action();
*/ } /**
* 接收客户端传过来的消息事件
* @param $ws
* @param $frame
*/
public function onMessage($ws, $frame) {
$msg=$frame->data;//接收客户端传过来的消息
$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));
} /**
* ws客户端关闭时调用事件
* @param $ws
* @param $fd
*/
public function onClose($ws, $fd) {
echo "clientid:{$fd}\n";
} /**
* @param $serv
* @param $taskId
* @param $workerId
* @param $data
*/
public function onTask($serv, $taskId, $workerId, $data) { // 分发 task 任务机制,让不同的任务 走不同的逻辑
$obj = new app\common\lib\task\Task; $method = $data['method'];
$flag = $obj->$method($data['data'], $serv);
/*$obj = new app\common\lib\ali\Sms();
try {
$response = $obj::sendSms($data['phone'], $data['code']);
}catch (\Exception $e) {
// todo
echo $e->getMessage();
}*/ return $flag; // 告诉worker
} /**
* @param $serv
* @param $taskId
* @param $data
*/
public function onFinish($serv, $taskId, $data) {
echo "taskId:{$taskId}\n";
echo "finish-data-sucess:{$data}\n";
} } new Ws();
因为tp里面的全局变量会在进程的内存里面不变,会导致执行地址path不更新,需要修改源代码
修改框架源代码thinkphp/library/think/Request.php,两处地方,如下2图:

上面是服务端websocket代码,下面是客户端JS
<script>
var wsServer = 'ws://193.112.27.236:9501/index/login/a?cc=1'; //websocket服务端地址,记住ws://不能去掉
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
websocket.send(1111);//发送数据给服务器
}; //服务端关闭时调用
websocket.onclose = function (evt) {
console.log("Disconnected");
}; //服务端向客户端发送消息时调用
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
}; //服务端报错时调用
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
</script>

  注意:linux上面运行开启服务时

php ws.php

以上命令可能会有问题,因为cli模式下运行的php 可能跟你项目运行的php版本跟配置文件不一样

可以使用以下命令来保证准确:

查看是否启动成功

修改代码之后,需要杀死进程,重新启动

swoole结合支持thinkphp 5.0版本的更多相关文章

  1. 不支持PowerShell 2.0版本(don't support PowerShell version 2.0. )

    在“程序包管理器控制台”使用命令“update-database”会提示:The Entity Framework Core Package Manager Console Tools don't s ...

  2. Thinkphp 3.0版本上传文件加图片缩略图实例解析

    先看html加个表单,注意这里的action 路径要选 对. <div> <form action="__URL__/add_img" enctype=" ...

  3. RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V3.0 版本强势发布

    继上个版本“RDIFramework.NET V2.9版本”的推出,受到了重多客户的认可与选择,V2.9版本是非常成功与稳定的版本,感谢大家的认可与长期以来的关注与支持.V3.0版本在V2.9版本的基 ...

  4. thinkphp 6.0 swoole扩展websocket使用教程

    前言 ThinkPHP即将迎来最新版本6.0,针对目前越来越流行Swoole,thinkphp也推出了最新的扩展think-swoole 3.0. 介绍 即将推出的tp6.0,已经适配swoole.并 ...

  5. iOS开发---百度地图配置流程,2.6.0 版本 支持64位

      1.首先需要在百度地图下载最新SDK:地址: http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download 2. ...

  6. Spring.Net.FrameworkV3.0 版本发布了,感谢大家的支持

    Spring.Net.FrameworkV3.0 版本发布了,感谢大家的支持. Spring.Net.Framework,基于.NET的快速信息化系统开发.整合框架,为企业或个人在.NET环境下快速开 ...

  7. PyQt 5.2 发布,此版本完全支持Qtv5.2.0

    PyQt 5.2 发布,此版本完全支持Qtv5.2.0 :包括了新的 QtBluetooth,QtPositioning,QtMacExtras,QtWinExtras 和 Qt11Extras 模板 ...

  8. 图文解说PhpStorm 7.0版本支持PHP 5.5

    PhpStorm7.0版本终于在2013年与广大开发者见面了!鉴于PhpStorm 7.0测试版中对PHP语言最新版的支持,JetBrains没让大家失望,PhpStorm 7.0正式版本中,最大的变 ...

  9. 在vs2017 版本15.7.6中不支持2.1.0以上版本的net core sdk

    问题起因 :使用.net core 2.1sdk 电脑直接安装的2.1.1 没有安装2.1.0的sdk 在项目开发过程中报错:当前 . NET SDK 不支持将 .NET Core 2.1.1 设置为 ...

随机推荐

  1. 企业SQL笔试

    Student(SID, Sname, Sage, Ssex) 学生表        Course(CID, Cname, TID) 课程表        SC(SID, CID, score) 成绩 ...

  2. numpy用法

    NumPy中创建特殊值 np.nan    np.inf nan表示数据空缺   inf表示无穷 参考:https://www.cnblogs.com/haoxi/p/9175781.html

  3. 我发起了一个 用 javascript 写一个 Office 的 开源项目 JS Office

    用   js  写   Office,  说实在的,  把 现在已有的 各种 富文本编辑器 和 电子表格 js 库 收集起来 整合一下 就 差不多了 , 放到 前几天 那个 “  js 作为 一等公民 ...

  4. org.apache.commons等常用工具学习

    StringUtils 1,StringUtils.isNotBlank isNotEmpty : 判断某字符串是否非空 StringUtils.isNotEmpty(null) = false St ...

  5. 一维信号频谱图仿真——matlab

    程序1: %在MATLAB中是用连续信号在等时间间隔点的样值来近似地表示连续信号的,当采样时间间隔足够小时,这些离散的采样值就能较好地近似出连续信号,matlab中连续信号的显示实际上还是离散信号的显 ...

  6. [总结] Synchronized汇总

    Java中的每一个对象都可以作为锁. 1对于同步方法,锁是当前实例对象. 2对于静态同步方法,锁是当前对象的Class对象. 3对于同步方法块,锁是Synchonized括号里配置的对象. 当一个线程 ...

  7. C++标准模板类库(STL)之queue初步

    1,STL里有些什么? 包括三个内容:容器.迭代器.算法. 2,容器有哪些? 有stack, vector, queue, deque, list, set, multiset, map, multi ...

  8. 浅谈C#在网络波动时防重复提交

    前几天,公司数据库出现了两条相同的数据,而且时间相同(毫秒也相同).排查原因,发现是网络波动造成了重复提交. 由于网络波动而重复提交的例子也比较多: 网络上,防重复提交的方法也很多,使用redis锁, ...

  9. bat文件与Vbs文件常用操作(获取用户输入,执行VBS文件)

    bat文件: set /P StrInput="输入数字:" echo 输入的数字为%StrInput% set /P Flg="是否执行(y/n):" IF ...

  10. MySQL-exists和in的区别

    SQL查询中in和exists的区别分析 对于一些不可不免的查询场景,我们难免要用到子查询 那么in和exists那个的效率更高一点呢 SQL查询中in和exists的区别分析 select * fr ...