Table of contents
Directory
Updated at 2020-03-20 16:00:22

TarsPHP

1 Intro

tars-client

The PHP ability to call the tars service is provided in the tars-client, including:

  • Call the instance of the remote service;
  • Call stat info report
  • Automatic failover

tars-server

Tars-server provides the underlying server framework and supports the following features:

  • High performance service based on swoole1.x/2.x
  • Support two protocol modes: tup protocol and tars stream
  • Support three kinds of servers: http, TCP and timer
  • Reporting, monitoring and log integration
  • Tars platform publish support

tars-config

The ability module to pull configuration files from the configuration service of the tars platform.

tars-deploy

The module that packs the business code of tars-server.

tars-extension

The PHP extension code that tars relies on

tars-log

Modules of remote log writing by tars

tars-monitor

The function modules of main dispatching report and characteristic report of tars

tars-registry

The function module of tars for master addressing

tars-report

The module of keeping alive service reporting by tars

tars-utils

Modules of configuration file parsing by tars

tars2php

The tool of automatic code generation can automatically generate server and client code.

2 Create Http HelloWorld

Directory structure description

  1. scripts: Store the scripts required by the business, such as tars2php.sh, which is responsible for generating the code required by the client according to the tars file
  2. src: The directory of business logic mainly includes the following structure:
  • component: The basic class of the storage controller is convenient for all controllers to share
  • conf: The configuration required by the business is just a demo. If the configuration is distributed from the platform, it will be written to this folder by default;
  • controller: C layer in MVC model
  • servant: The client source code generated by tars2php, the directory name can be completely customized, and only needs to be distinguished during use;
  • composer.json: Explain project dependencies
  • index.php: The entry file of the whole service. The file name can be customized, but the private template on the platform must be changed. Add the entry field under the server
  • services.php: Declare the base namespace name of the entire project
  • tars: The TCP service depends on the example.tars file under this folder and the tars.client.proto.php file, which are necessary for generating code under the service. This will be explained in the following guide line.

Service Deployment

  1. Enter operation => template

The platform will provide a template for PHP named tars.tarsphp.default

You must first modify the execution path of PHP in it

  1. Enter operation => deploy
App         = match tars.proto.php in the tar folder below
Server Name = match tars.proto.php in the tar folder below
Server Type = tars_php
Template    = tars.tarsphp.default
obj         = match tars.proto.php in the tar folder below
NodeName    = tarsnode node ip
Port        = server port
Port Type   = TCP
Protocol    = NOT TARS

Notice:

  • Protocol type HTTP service must select non tars
  • The number of threads corresponds to the number of processes in swoole
  • The maximum number of connections, maximum queue length and queue timeout are not valid for PHP services

Develop Guideline

Basic steps:

  1. Create a new directory structure, and fix it to scripts, src, and tars
  2. Create src/composer.json
{
  "name": "tars/helloworld/phphttp",
  "description": "tars php http hello world",
  "require": {
    "phptars/tars-server": "~0.2",
    "phptars/tars-deploy": "~0.1",
    "phptars/tars2php": "~0.1",
    "phptars/tars-log": "~0.1",
    "ext-zip": ">=0.0.1"
  },
  "autoload": {
    "psr-4": {
      "PHPHttp\\": "./"
    }
  },
  "minimum-stability": "stable",
  "scripts": {
    "deploy": "\\Tars\\deploy\\Deploy::run"
  }
}
  1. Create src/index.php
<?php
/**
 * Platform entrypoint
 */
require_once __DIR__.'/vendor/autoload.php';

use \Tars\cmd\Command;

//php index.php  conf restart
$config_path = $argv[1];
$pos = strpos($config_path, '--config=');

$config_path = substr($config_path, $pos + 9);

$cmd = strtolower($argv[2]);

$class = new Command($cmd, $config_path);
$class->run();
  • This will cause platform and requirement initialization.
  1. Create src/services.php
<?php
return [
    // Hello is the object name
    'Hello' => [
        'namespaceName' => 'PHPHttp\\', // psr4 root namespace
        'saveTarsConfigFileDir' => 'src/conf/', // config directory
        'saveTarsConfigFileName' => ['',], // Config files which need to be pulled from Tars framework.
        'monitorStoreConf' => [
            //'className' => Tars\monitor\cache\RedisStoreCache::class,
            //'config' => [
            // 'host' => '127.0.0.1',
            // 'port' => 6379,
            // 'password' => ':'
            //],
            'className' => Tars\monitor\cache\SwooleTableStoreCache::class,
            'config' => [
                'size' => 40960
            ]
        ],
        'registryStoreConf' => [
            'className' => Tars\registry\RouteTable::class,
            'config' => [
                'size' => 200
            ]
        ],
        'protocolName' => 'http', //http, json, tars or other
        'serverType' => 'http', //http(no_tars default), websocket, tcp(tars default), udp
    ],
];

namespaceName should match the psr4 settings in composer.json.

monitorStoreConf is the stats report storage configuration

  • className is the storage class name. Use \Tars\monitor\cache\SwooleTableStoreCache::class for _swooletable as default. tars-monitor allow you to use redis redis instead. You can also build your own storage class by implement \Tars\monitor\contract\StoreCacheInterface.
  1. run composer install
  2. Create tars/tars.proto.php to define your servant
<?php
return [
    'appName' => 'HelloWorld',
    'serverName' => 'PHPHttp',
    'objName' => 'Hello',
];
  • appName, serverName, objName should be exactly as the servant you deployed.
  1. Create src/component/Controller.php
<?php

namespace PHPHttp\component;

use Tars\core\Request;
use Tars\core\Response;

class Controller
{
    protected $request;
    protected $response;

    public function __construct(Request $request, Response $response)
    {
        $this->request = $request;
        $this->response = $response;
    }

    public function getResponse()
    {
        return $this->response;
    }

    public function getRequest()
    {
        return $this->request;
    }

    public function cookie($key, $value = '', $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = false)
    {
        $this->response->cookie($key, $value, $expire, $path, $domain, $secure, $httponly);
    }

    // send raw data to client
    public function sendRaw($result)
    {
        $this->response->send($result);
    }

    public function header($key, $value)
    {
        $this->response->header($key, $value);
    }

    public function status($http_status_code)
    {
        $this->response->status($http_status_code);
    }
}

  • This is the base class for all Controllers.
  1. Create src/controller/IndexController.php
<?php

namespace PHPHttp\controller;

use PHPHttp\component\Controller;
use Tars\client\CommunicatorConfig;
use Tars\App;

class IndexController extends Controller
{
    public function actionIndex()
    {
        $this->sendRaw('Hello Tars!');
    }
}
  • The accessable url for this action is http://{machine_ip}:9000/index/index
  1. Run composer run-script deploy in src directory to build deployment package.
  2. Upload src/PHPHttp_xxx.tar.gz and deploy
  • You can find app logs in /data/app/tars/app_log/HelloWorld/PHPHttp if the service if failed to start.

3. Create Tars HelloWorld

Directory structure description

  1. scripts: Store the scripts required by the business, such as tars2php.sh, which is responsible for generating the code required by the client according to the tars file
  2. src: The directory of business logic mainly includes the following structure:
  • component: The basic class of the storage controller is convenient for all controllers to share
  • conf: The configuration required by the business is just a demo. If the configuration is distributed from the platform, it will be written to this folder by default;
  • impl: Tars api logic
  • servant: The client source code generated by tars2php, the directory name can be completely customized, and only needs to be distinguished during use;
  • composer.json: Explain project dependencies
  • index.php: The entry file of the whole service. The file name can be customized, but the private template on the platform must be changed. Add the entry field under the server
  • services.php: Declare the base namespace name of the entire project
  • tars: The TCP service depends on the example.tars file under this folder and the tars.client.proto.php file, which are necessary for generating code under the service. This will be explained in the following guide line.

Deploy servant

AppName = HelloWorld
ServerName = PHPTars
ObjName = Hello

Develop guideline

  1. Create scripts/tars2php.sh
#!/bin/bash

cd ../tars/

php ../src/vendor/phptars/tars2php/src/tars2php.php ./tarsclient.proto.php

  • Use this script to generate code based on the definations in tarsclient.proto.php
  1. Create src/composer.json
{
  "name": "tars/helloworld/phptars",
  "description": "tars php hello world",
  "require": {
    "phptars/tars-server": "~0.2",
    "phptars/tars-deploy": "~0.1",
    "phptars/tars2php": "~0.1",
    "phptars/tars-log": "~0.1",
    "ext-zip": ">=0.0.1"
  },
  "autoload": {
    "psr-4": {
      "PHPTars\\": "./"
    }
  },
  "minimum-stability": "stable",
  "scripts": {
    "deploy": "\\Tars\\deploy\\Deploy::run"
  },
  "repositories": {
    "packagist": {
      "type": "composer",
      "url": "https://mirrors.aliyun.com/composer/"
    }
  }
}
  • Run composer install after composer.json created.
  1. Create platform entrypoint src/index.php
<?php
/**
 * platform entrypoint
 */
require_once __DIR__.'/vendor/autoload.php';

use \Tars\cmd\Command;

//php index.php  conf restart
$config_path = $argv[1];
$pos = strpos($config_path, '--config=');

$config_path = substr($config_path, $pos + 9);

$cmd = strtolower($argv[2]);

$class = new Command($cmd, $config_path);
$class->run();
  1. Create service config file src/services.php
<?php
return [
    // Hello is the ObjName in service deploy form
    'Hello' => [
        'home-api' => '\PHPTars\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant',
        'home-class' => '\PHPTars\impl\SayHello',
        'protocolName' => 'tars', //http, json, tars or other
        'serverType' => 'tcp', //http(no_tars default), websocket, tcp(tars default), udp
    ],
];

  1. Create tars/tars.proto.php
<?php
return [
    'appName' => 'HelloWorld',
    'serverName' => 'PHPTars',
    'objName' => 'Hello',
];

  1. Create tars/tarsclient.proto.php
<?php
return array(
    'appName' => 'HelloWorld',
    'serverName' => 'PHPTars',
    'objName' => 'Hello',
    'withServant' => true, // The tars2php.sh script will generate server code for true, client code for false.
    'tarsFiles' => array(
        './SayHello.tars', // tars file location based on tars directory. Only support one file for tars server.
    ),
    'dstPath' => '../src/servant', // The target direcoty for code generating. Location is based on scripts directory
    'namespacePrefix' => 'PHPTars\servant',
);
  • Define the code generating parameters
  1. Create tars/SayHello.tars
module SayHelloTafServiceServant
{
    interface SayHelloTafService
    {
        int greeting(string name, out string greeting); // out stands for output parameter.
    };

};
  1. Create src/impl/SayHello.php to implement tars API
<?php

namespace PHPTars\impl;

use PHPTars\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant;

class SayHello implements SayHelloTafServiceServant
{
    public function greeting($name, &$greeting)
    {
        $greeting = "PHPTars says hello to $name";

        return 0;
    }
}

  • This class is what we set in home-class. see src/services.php
  1. Run composer run-script deploy in src directory to build a deployment package
  2. Deploy tars service to node
  • You can access HelloWorld.PHPHttp service page to test this API on debug tool.
  • You can find app logs in /data/app/tars/app_log/HelloWorld/PHPTars on node machine if service is failed to start.

4. Create Tars HelloWorld Client

  • Let's call the tars API in PHPHttp project.
  1. Copy SayHello.tars to tars/SayHello.tars
  2. Create tars/tarsclient.proto.php
<?php

return array(
    'appName' => 'HelloWorld',
    'serverName' => 'PHPHttp',
    'objName' => 'Hello',
    'withServant' => false, //false for client code generating
    'tarsFiles' => array(
        './SayHello.tars',
    ),
    'dstPath' => '../src/servant',
    'namespacePrefix' => 'PHPHttp\servant',
);
  • Execute scripts/php2tars.php to generate client code.
  1. Add new action to src/controller/IndexController.php
    public function actionTestGreeting()
    {
        $config = new \Tars\client\CommunicatorConfig();
        $config->setLocator(\Tars\App::$tarsConfig['tars']['application']['client']['locator']);

        $userService = new \PHPHttp\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant($config);
        $greeting = '';
        $return = $userService->greeting('Frank Lee', $greeting);

        $this->sendRaw(json_encode(compact('return', 'greeting')));
    }
  • PHPHttp\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant is generated by tars2php.sh
  • \Tars\App::$tarsConfig will be initialized by tars configs after service started.
  • \Tars\App::$tarsConfig['tars']['application']['client']['locator'] is the location of registry object which provide route service for tars nodes.
  • !!!! Tars is a multi-language platform. We must initialize parameters with proper type before we made the call. !!!!
  1. Package you code and deploy
  • You can check the result by access http://{machine_ip}/index/TestGreeting
Chapter