`

swoole提供http服务

 
阅读更多

swoole是一个php的网络通信框架,可以简单支持http服务。按照官方介绍,如果遇到mysql或者广播消息等耗时或阻塞的业务,需要开启task去提供服务,在Finish回调中处理结果(定时器中如果有阻塞任务,会导致work进程无法提供服务)。

(需要安装配置扩展,如果源码编译运行提示glibc版本不兼容,可以用pecl install swoole)

针对一些数据不常变化的部分,我们可以用定时器读取到内存,然后提供服务,这样对mysql压力小了很多。大致示例代码如下:

#!/usr/bin/php
<?php 

date_default_timezone_set("Asia/Shanghai");
class RotateMap
{
	public function __construct ()
	{
		$this->d = array(array(), array());
		$this->idx = 0;
	}
	public function &get ()
	{
		return $this->d[$this->idx];
	}
	public function set ($t)
	{
		$this->d[!$this->idx] = $t;
		$this->swap();
	}
	private function swap ()
	{
		$this->idx = !$this->idx;
	}
	private $d;
	private $idx;
};

class Server
{
	private $serv;

	private $upgrade;
	private $allowurl;
	private $checkurl;

	const RELOAD_SECOND_INTERVAL 	= 1000;
	const RELOAD_MINUTE_INTERVAL 	= 60000;
	const RELOAD_HOUR_INTERVAL 	= 360000;
	const RELOAD_DAY_INTERVAL 	= 86400000;
	const ERROR_LOG = "/tmp/swoole.error.log";
	const LOCAL_TXT = "/tmp/localfile";

	public function __construct ()
	{
		$this->upgrade = new RotateMap();
		$this->allowurl = new RotateMap();
		$this->checkurl = new RotateMap();

		$this->serv = new swoole_http_server("127.0.0.1", 1987);
		$this->serv->set(array('worker_num' =>1,
					'daemonize' => true,
					'max_request' =>10000,
					'dispatch_mode' =>3,
					'debug_mode' =>1,
					'task_worker_num' =>1,
					'log_file' =>'/tmp/swoole.log'));

		$this->serv->on('Start', array($this, 'onStart'));
		$this->serv->on('Request', array($this, 'onRequest'));
		$this->serv->on('Task', array($this, 'onTask'));
		$this->serv->on('Finish', array($this, 'onFinish'));
		$this->serv->on('WorkerStart', array($this, 'onWorkerStart'));
		$this->serv->on('Timer', array($this, 'reloadDB'));

		$this->serv->start();
	}

	public function onStart($serv)
	{
	}

	private function slog($msg){
		echo "[".date('Y-m-d H:i:s')." #".$this->serv->worker_pid.".0]  INFO  ".$msg.PHP_EOL;
	}

	public function onWorkerStart($serv, $worker_id)
	{
		if($serv->taskworker == false){
			//Init Data
			$this->slog("InitData Begin");
			$this->reloadDBUpgrade(true);
			$this->reloadDB1(true);
			$this->reloadDB2(true);
			$this->slog("InitData Done");

			$serv->addtimer(Server::RELOAD_HOUR_INTERVAL);
		}
	}

	private function reloadDBUpgrade($save = false){
		try{
			$dsn='mysql:host=myhost;dbname=mydb;';
			$dbh=new PDO($dsn,"myusername","mypassword");
			$dbh->query('set names utf8;');
			$stmt=$dbh->query('SELECT id,name FROM tb_version ORDER BY id DESC LIMIT 1');

			while($row = $stmt->fetch()){
				$verinfo = array(
						"id" => $row["id"],
						"name" => $row["name"],
						);

				break;
			}
		}
		catch(PDOException $e){
			error_log($e->getMessage(),3,Server::ERROR_LOG);	
		}

		$dbh = null;
		if($save){
			$this->upgrade->set($verinfo);
		}else{
			return $verinfo;
		}
	}

	private function reloadDB1($save = false){
		$handle  = fopen(Server::LOCAL_TXT, "r");
		if(!$handle){
			return;
		}
		$data = array();
		while (!feof ($handle))
		{
			$buffer  = fgets($handle, 1024);
			$domain = trim($buffer);
			if(strlen($domain)>=5){
				array_push($data, $domain);
			}
		}
		fclose ($handle);
		if($save){
			$this->allowurl->set($data);
		}else{
			return $data;
		}
	}

	private function reloadDB2($save = false){
		$handle  = fopen(Server::CHECK_TXT, "r");
		if(!$handle){
			return;
		}
		$data = array();
		while (!feof ($handle))
		{
			$buffer  = fgets($handle, 1024);
			$info = explode("|",trim($buffer));
			if(count($info)==2){
				$domain = $info[0];
				$sortid = $info[1];
				if(strlen($domain)>=5 && is_numeric($sortid)){
					$data[$domain] = $sortid;
				}
			}
		}
		fclose ($handle);
		if($save){
			$this->checkurl->set($data);
		}else{
			return $data;
		}
	}

	public function reloadDB($serv, $interval)
	{
		switch($interval)
		{
			case Server::RELOAD_HOUR_INTERVAL:
				$param = array("job", "reload");
				$serv->task($param);
				break;
		}
	}

	public function onRequest (swoole_http_request $request,
			swoole_http_response $response)
	{
		$code = 200;
		$request_uri = $request->server["request_uri"];
		$request_method = $request->server["request_method"];
		$remote_addr = $request->server["remote_addr"]; 
		$getdata = $postdata = '{}';
		if(isset($request->get)){
			$getdata = json_encode($request->get);
		}
		if(isset($request->post)){
			$postdata = json_encode($request->post);
		}
		$this->slog("$remote_addr $request_method $request_uri $getdata $postdata");
		switch($request_uri){
			case '/url1':
				$id =isset($request->get["id"])?$request->get["id"]:null;
				if($id == null){
					$code = 400;
					$res = "400 bad request";
				}else{
					$data = &$this->upgrade->get();
					if($id == $data["id"]){
						$res = array("hasNewVersion"=>false);
					}else{
						$res = array("hasNewVersion"=>true,"versionInfo"=>$this->upgrade->get());
					}
				}
				$res = json_encode($res, JSON_UNESCAPED_SLASHES);
				break;
			case '/url2':
				$host = isset($request->post["host"])?$request->post["host"]:null;
				$referer = isset($request->post["referer"])?$request->post["referer"]:null;

				$v1 = 1;
				$v2 = 1;
				$data = &$this->allowurl->get();
				if($host){
					$info = explode(".", $host);
					if(count($info)>=2){
						$host = $info[count($info)-2].".".$info[count($info)-1];
					}

					if(in_array($host,$data)){
						$v1 = 0;
					}	
				}
				if($referer){
					$info = explode(".", $referer);
					if(count($info)>=2){
						$referer = $info[count($info)-2].".".$info[count($info)-1];
					}
					if(in_array($referer,$data)){
						$v2 = 0;
					}	
				}
				$res = "$v1|$v2";
				break;
			case '/url3':
				$host = isset($request->post["host"])?$request->post["host"]:null;
				$url = isset($request->post["url"])?$request->post["url"]:null;

				$data = &$this->checkurl->get();
				$v1 = 0;
				if($host){
					$info = explode(".", $host);
					if(count($info)>=2){
						$host = $info[count($info)-2].".".$info[count($info)-1];
					}
					if(array_key_exists($host,$data)){
						$v1 = $data[$host];
					}
				}

				$res = $v1;
				break;
			default:
				$code = 404;
				$res = "404 not found";

		}
		$response->status($code);
		$response->header("Server", "nginx");
		$response->header("Content-Type", "text/html");
		$response->end($res);
	}

	public function onTask ($serv, $task_id, $from_id, $data)
	{
		$this->slog("ReloadData Begin");
		$ret = array();
		$ret["upgrade"] = $this->reloadDBUpgrade();
		$ret["allowurl"] = $this->reloadDB1();
		$ret["checkurl"] = $this->reloadDB2();
		$this->slog("ReloadData Done");
		return $ret;
	}

	public function onFinish ($serv, $task_id, $data)
	{
		if(count($data["allowurl"])>0){
			$this->allowurl->set($data["allowurl"]);
		}else{
			error_log("load allowurl error",3,Server::ERROR_LOG);	
		}
		if(count($data["checkurl"])>0){
			$this->checkurl->set($data["checkurl"]);
		}else{
			error_log("load checkurl error",3,Server::ERROR_LOG);	
		}
		$this->upgrade->set($data["upgrade"]);
	}
}

$server = new Server ();
?>
分享到:
评论

相关推荐

    Laravel开发-laravel-swoole-http

    4. **热更新**:Laravel Swoole HTTP 服务器支持热更新,可以在不中断服务的情况下更新代码,保证了应用的高可用性。 5. **WebSocket 支持**:结合 Laravel,可以轻松构建实时通信应用,如聊天室、推送通知等。 6....

    php7及以上版本 swoole扩展

    Swoole是一个高性能的PHP扩展,专为网络并发设计,提供了异步多线程服务器、异步TCP/UDP网络客户端、HTTP服务器、WebSocket服务器、MySQL协议服务器等功能。它极大地提升了PHP处理高并发、长连接场景下的性能,使得...

    swoole-yaf, 结合swoole扩展和Yaf框架,使用swoole的内置http_server.zip

    其中,Swoole的内置HTTP服务器功能,允许开发者用PHP编写高性能的Web服务,它支持HTTP、HTTPS、WebSocket协议,并且可以无缝对接PHP现有的Web框架。 二、Yaf框架简介 Yaf(Yet Another Framework)是由著名的PHP...

    Swoole实战之手撸HttpServer框架

    在IT行业中,Swoole是一个高性能、异步、并行的PHP扩展,它为PHP提供了原生的网络通信框架,极大地提升了PHP处理TCP、UDP、HTTP等网络协议的能力。本篇将聚焦于"Swoole实战之手撸HttpServer框架"这一主题,探讨如何...

    swoole2.0.9下载,swoole2源码下载

    - HTTP/2支持:在2.0.9版本中,Swoole已经支持HTTP/2协议,能够提供更高效的HTTP服务。 - WebSocket服务器:Swoole提供了完整的WebSocket服务器端实现,支持WebSocket协议的各种特性。 3. **安装与使用** - 下载...

    PHP扩展swoole,PHP7及以上版本可用

    4. **HTTP服务器**:Swoole提供全功能的HTTP服务器,包括HTTP/1.1、HTTP/2协议,以及WebSocket协议。可以用于构建RESTful API服务或者WebSocket实时通信服务。 5. **WebSocket服务器**:Swoole的WebSocket服务器...

    swoole4.x框架

    3. HTTP/HTTPS/WebSocket 服务器:Swoole 可以搭建高性能的 HTTP、HTTPS 服务器,并支持 WebSocket 协议,为 Web 应用提供实时通信能力。 4. TCP/UDP 服务器:除了 HTTP,Swoole 还能用于构建 TCP 和 UDP 服务,广泛...

    一个高性能的HTTP服务器来加速基于Swoole的LaravelLumen应用

    1. **Swoole扩展**:Swoole是PHP的一个C语言编写的扩展,提供了TCP、UDP、HTTP、WebSocket等多种网络协议的服务器和客户端接口,支持异步非阻塞I/O和协程,极大地提高了PHP处理高并发的能力。 2. **PHP-FPM与Swoole...

    lumen-swoole-http:lumen swoole http服务器

    这个项目的主要目标是提供一个高效、高性能的Web服务解决方案,利用Swoole的异步、非阻塞I/O模型来增强Lumen微服务架构的能力。 【描述】提到,"该存储库已存档,不再维护。推荐使用其他的首选替代品"。这表明Lumen...

    在swoole服务中测试发送、回复代码

    在IT行业中,Swoole是一个高性能的PHP扩展,它提供了异步、并行处理能力,使得PHP能够构建常驻内存的Web服务,极大地提升了效率。本文将深入探讨如何在Swoole服务中进行消息的发送与接收,以及相关联的HTML、...

    Swoole扩展

    Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。 Swoole可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用PHP+Swoole作为网络通信框架,...

    基于swoole实现的自带httpserver的web开发框架

    总的来说,基于Swoole的Web开发框架为PHP开发者提供了一种高效、灵活的解决方案,它利用Swoole的优势,让PHP在处理网络服务时具备了更强的竞争力。无论是对于新手还是经验丰富的开发者,理解并掌握这样的框架都是...

    Laravel开发-swoole

    描述中提到"Swoole是基于Swoole的高性能HTTP服务器",这意味着Swoole不仅能够作为PHP的扩展,还提供了用于构建HTTP服务器的基础设施。它能够加速Laravel和Lumen这两个PHP微服务框架的应用程序,通过利用其非阻塞I/O...

    Swoole框架PHP 异步网络通信引擎swoole-v5.1.2.zip

    2. API服务器:对于高并发的API接口,Swoole可以提供更快的响应速度和更高的吞吐量。 3. Websocket服务:Swoole的WebSocket服务器可以轻松处理大量用户的实时交互需求,如游戏服务器、在线教育等。 4. 调度任务:...

    swoole_loader 拓展包 支持win和linux

    Swoole是一个高性能、异步、并行的PHP扩展,它允许开发人员利用C语言编写的Swoole库来实现网络通信服务,如HTTP服务器、WebSocket服务器、TCP服务器等。Swoole_Loader的出现,极大地简化了在不同PHP版本和操作系统上...

    swoole分布式通讯框架

    3. **TCP/UDP服务器**:Swoole提供了TCP、UDP服务端和客户端接口,可以轻松实现高并发的网络服务。 4. **WebSocket服务器**:Swoole支持WebSocket协议,方便构建实时的双向通信应用,如聊天室、游戏服务器等。 5. ...

    php7.0以上swoole扩展

    - **TCP/UDP/WebSocket服务器**:Swoole可以直接创建TCP、UDP服务,甚至WebSocket服务器,非常适合构建高性能的网络应用。 - **HTTP/HTTPS服务器**:支持完整的HTTP/2协议,可以搭建高性能的API服务器或者静态文件...

    Swoole Loader扩展.7z

    Swoole扩展为PHP提供了原生的多线程、多进程、TCP/UDP网络通信、HTTP服务器、WebSocket服务器等功能。通过Swoole,PHP可以脱离传统的请求-响应模型,进入常驻内存、事件驱动的编程模式,从而实现更高的性能和更低的...

    swoole学习文档

    3. 服务器(Server):Swoole提供了TCP、UDP、HTTP、WebSocket等多种协议的服务器实现,可以处理海量并发连接。 4. 客户端(Client):Swoole也提供了对应的客户端类,方便进行服务器通信。 5. 异步任务(Async ...

    用swoole来实现Yarserver

    Swoole提供了TCP/UDP套接字、HTTP服务器、WebSocket服务器等功能,能够实现异步非阻塞IO,极大地提升了PHP的性能。 接下来,我们将结合Swoole实现Yarserver的步骤: 1. **安装Swoole扩展**:确保你的PHP环境已经...

Global site tag (gtag.js) - Google Analytics