hebbinkpro / pmmp-webserver
A HTTP/1.1 webserver Virion for PocketMine plugins
Requires
- php: ^8.1
- pocketmine/pocketmine-mp: ^5.0.0
Requires (Dev)
- laravel/serializable-closure: v1.3.0
- phpstan/extension-installer: ^1.2.0
- phpstan/phpstan: ^1.10.3
- phpstan/phpstan-strict-rules: ^1.5.0
README
一个用于 PocketMine-MP 插件创建简单 HTTP/1.1 网络服务器的版本。
插件
- 该病毒体用于我的 Dynmap 类似插件
PocketMap
。您可以在这里找到插件
如何安装
- 从 Poggit CI 下载最新版本的 phar 构建
- 或直接使用 composer 安装:
composer require hebbinkpro/pmmp-webserver
如何使用
创建网络服务器
为了创建网络服务器,您必须注册 WebServer 并创建一个新的 WebServer
实例以启动服务器。
<?php use Hebbinkpro\WebServer\WebServer; use Hebbinkpro\WebServer\http\server\HttpServerInfo; class YourPlugin extends \pocketmine\plugin\PluginBase { protected function onEnable() : void{ // ... $serverInfo = new HttpServerInfo("0.0.0.0", 80) // Create a new server on the address and port $webServer = new WebServer($this, $serverInfo); // after starting the server, the site will be available at http://127.0.0.1:80 $webServer->start(); } }
请注意,如果您想从您的 localhost 或本地网络之外访问服务器,您可能需要进行端口转发,否则它将无法对外部网络可用!
路由
路由用于让您的网络服务器能够执行操作。通过创建一个 Route
,您可以使您的网络服务器监听不同的路径并对它们做出响应。
路由器
路由器用于注册所有路由。路由器还将处理所有传入请求并确保它们由正确的 Route
处理。
您可以通过调用以下方式访问您的 WebServer
的路由器:
$router = $webServer->getServerInfo()->getRouter();
Route
路由用于对传入的 Web 请求执行操作。
use Hebbinkpro\WebServer\http\HttpMethod; use Hebbinkpro\WebServer\http\message\HttpRequest; use Hebbinkpro\WebServer\http\message\HttpResponse; use Hebbinkpro\WebServer\route\Route; { // the method can be any value in the HttpMethod class. // these methods represent HTTP request methods and makes the route listen to a specific type of request. // if you want to listen to all requests, you can use HttpMethod::ANY (or "*"). $method = HttpMethod::GET; // the specific path the route will listen to, // you can find out more about the paths below $path = "/"; // the action is the part that will execute once a client makes a request to the given method AND path. // the HttpRequest inside the function is the request the client made to the web server // the HttpResponse is the response the server will send back to the client after the function returns. $action = function (HttpRequest $request, HttpResponse $response) { // This will send the string "Hello World" back to the client. $response->text("Hello World"); // the text function is one of the many simplified versions of the 'send' function // by using the send function, you can input a string and set the HTTP content type // the example below will send the string "<h1>Hello World</h1>" to the client and the client will see it as an HTML file. $response->send("<h1>Hello World</h1>", "text/html"); // You can also send complete files using Response. // this makes it really easy to send any kind of file $response->sendFile("/path/to/your/file"); // but remember, you can only use ONE response action at any time // each new response action will OVERWRITE the previous. // So if you want to send multiple things in a single response, // consider splitting it in multiple files, or sending everything in 1 response } // now we construct the Route with our given method, path and action. $route = new Route($method, $path, $action); }
路由动作
路由动作是在将新请求发送到正确路径时执行的任务。动作的语法是
function (HttpRequest $request, HttpResponse $response, mixed ...$params) { // your code }
$request
是传入的请求$response
是将返回给客户端的响应...$params
是包含所有给定参数的数组。参数在新的Route
的末尾给出。
$route = new \Hebbinkpro\WebServer\route\Route($method, $action, ...$params);
您可以添加任意多的参数,如果您只想有一个参数,您可以使用 new Route($method, $path, $action, $param1)
,但如果您想有多个,您可以将它们添加到第一个参数之后。new Route($method, $path, $action, $param1, $param2, $param3)
。不添加参数也是选项之一,new Route($method, $path, $action)
。
要在动作中使用 ...$params
变量,您可以使用它作为一个数组,所以 $params[0]
将返回第一个参数,而 $params[1]
将给出第二个,依此类推。
不要在动作函数内部放置任何使用主线程的代码。动作必须是 ThreadSafe
的,因此只有不依赖于 PocketMine 线程的东西才能工作。如果您想使用不扩展 pmmp\thread\ThreadSafe
的类,您可以使用 serialize(...)
对参数进行序列化,并在动作函数内部使用 unserialize(...)
_
创建 HTTP 请求路由的路由器方法
对于最常用的方法,在 Router
实例内部有函数。这些函数使得您不必为每个新创建的 Route
输入 HTTP 方法
在 Router
中可用的方法函数有
- GET,仅监听 GET 请求的路由 -
Router->get($path, $action, ...$params)
- POST,仅监听 POST 请求的路由 -
Router->post($path, $action, ...$params)
- HEAD,仅监听 HEAD 请求的路由 -
Router->head($path, $action, ...$params)
- PUT,仅监听 PUT 请求的路由 -
Router->put($path, $action, ...$params)
- DELETE,仅监听DELETE请求的路由 -
Router->delete($path, $action, ...$params)
- USE(也称为ANY或*,在
Hebbinkpro\WebServer\http\HttpMethod
中),一个监听所有HTTP方法的路由 -Router->all($path, $action, ...$params)
关于HTTP请求方法的更多信息,请参阅这里
路由函数内部的路径和操作参数与Router
中的相同。
其他路由类型
在Router
中,除了默认的Route
实现外,您还可以使用以下三种类型的路由:
Route
- 一个基本路由,允许您为路径创建自己的响应FileRoute
- 一个发送文件作为响应的路由RouterRoute
- 一个作为Router
功能运行的路由,但仅针对指定的路径StaticRoute
- 一个允许您共享完整文件夹内容而不为每个不同的路径创建Route
的路由- 您不仅限于这些路由,还可以创建自己的路由。唯一的要求是您的自定义路由必须扩展(是
\Hebbinkpro\WebServer\route\Route
的子类)。您可以使用以下方式将Route
实例添加到Router
中:
$router->addRoute($route)
但是,Router
中也有函数可以轻松添加FileRoute
、RouterRoute
或StaticRoute
。
FileRoute
$file = "path/to/your/file"; $default = "File not found"; // add the file route, $default is optional $router->getFile($path, $file, $default);
RouterRoute
use Hebbinkpro\WebServer\router\Router; $childRouter = new Router(); // add here the stuff you want to the child router // this is the same as for a default router // ... // add the router route with the path and the newly created child router $router->route($path, $childRouter);
Static Route
// define the folder you want to use for the static route by using its path $folder = "/path/to/the/folder"; // add the static route with the path of the route and the folder path $router->getStatic($path, $folder)
路径
路由路径是URL中的路径,这些路径非常重要,因为它们包含客户端想要查看的页面信息。但是,为了确保客户端看到正确的页面,此页面的路径必须有一个Route
。这就是为什么对于您创建的每个Route
,如果它使用Router
中的函数或创建新的Route
实例,您必须提供一个有效的路径,否则客户端无法找到或请求您的页面。
默认路径
路径不过是地址后面的第一个/
之后到末尾或?
之间的所有内容。
前缀
有时您需要一个监听所有以/foo
开头的请求的路由,例如/foo/bar
或/foo/bar/etc
。
我们可以通过在路径末尾添加/*
来实现这一点。
参数
有时您需要一个前缀,但还需要一个后缀。为了实现这一点,我们引入了参数。参数是路径的一部分,可以是任何类型的字符串,因此路径/:var/a
将监听/foo/a
,但也将监听/bar/a
。更好的是,您还可以使用HttpRequest->getPathParams()
请求HttpRequest
内的所有变量,这将返回一个数组,其中以参数名称为键,以路径中的值设置为值。
查询
路径的查询是路径中?
后面的所有内容,例如/?foo=bar
。可以使用&
符号在两个值之间使用多个查询。单个查询表示为<name>=<value>
。
要请求所有查询,请使用HttpURI->getQuery()
,或要请求单个值,请使用HttpURI->getQueryParam($name)
。
HTTPS
从v1.0.0版本开始,Web服务器也支持SSL证书,这使得运行一个比HTTP更安全的HTTPS服务器成为可能。
要启用Web服务器的HTTPS,您必须在启动Web服务器之前将SslSettings
添加到HttpServerInfo
中。这可以通过多种方式完成。
- 让Web服务器通过调用
$webServer->detectSSL()
检测插件数据cert
文件夹中的SSL证书。 - 通过调用
$ssl = new SslSettings(...)
创建一个新的SslSettings
对象,并将其添加到HttpServerInfo
中:new HttpServerInfo(..., $ssl)
或者通过调用$serverInfo->setSSL($ssl)
。如果您在启动服务器后添加SSL设置,HTTPS将不会应用,并且您的服务器将作为一个普通的HTTP服务器运行。
致谢
- 该病毒利用Laravel\SerializableClosure来共享在主线程上通过
Router
给出的动作函数,以与http服务器线程共享。