PHP Websocket Healthcheck AWS ECS Fargate docker image - amazon-ecs

I want to create a single file when you have 2 classes, one for health check and another one for chat messaging.
So what I do is creating a docker image exposing port 9000 (ws://localhost:9000/chat) but also I need a health check in http://localhost:9000/health with http status code 200.
<?php
require '/vendor/autoload.php';
use Exception;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\RequestInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Http\HttpServerInterface;
class HealthSocketHandler implements HttpServerInterface
{
public function onMessage(ConnectionInterface $from, $msg)
{
//
}
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
{
$response = new Response(200, [
'Content-Type' => 'application/json',
], json_encode([
'ok' => true,
]));
$connection->send(\GuzzleHttp\Psr7\str($response));
$connection->close();
}
public function onClose(ConnectionInterface $connection)
{
//
}
public function onError(ConnectionInterface $connection, Exception $exception)
{
if (! $exception instanceof HttpException) {
return;
}
$response = new Response($exception->getStatusCode(), [
'Content-Type' => 'application/json',
], json_encode([
'error' => $exception->getMessage(),
]));
$connection->send(\GuzzleHttp\Psr7\str($response));
$connection->close();
}
}
class Chat implements MessageComponentInterface {...}
$loop = LoopFactory::create();
$app = new Ratchet\App("localhost", 9000, '0.0.0.0', $loop);
$app->route('/health', new HealthSocketHandler, array('*')); // health check | return 200 code
$app->route('/chat', new Chat, array('*'));
$app->run();
Also I have this second one sample
<?php
require '/vendor/autoload.php';
use Exception;
use React\EventLoop\Factory as LoopFactory;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
/* use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer; */
// Main class
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
$loop = LoopFactory::create();
$app = new Ratchet\App("localhost", 9000, '0.0.0.0', $loop);
$app->route('/chat', new Chat, array('*'));
//$app->route('/health', new React\Http\Response(200, ['Content-Type' => 'text/plain'], 'Hello, World'));
//$app->route('/health', new React\Http\Response(200), 'oK');
$app->run();
?\>
I need to know how to expose a Websocket App with health check
For websocket chat expose port 9000 (ws://localhost:9000/chat)
and a health check in http://localhost:9000/health with http status code 200.

Related

How to do queries with pdo db connection function?

I read too many questions and answers around but couldn't be sure.
I have 2 questions
1.I turned my db connection into a function and I am not sure if its
safe ?
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_NAME', 'demo');
function DB()
{
try {
$pdo = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_NAME.'', DB_USERNAME, DB_PASSWORD);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch (PDOException $e) {
return "Error!: " . $e->getMessage();
die();
}
}
2.is my query done right way ?
query:
try {
$pdo = DB();
$stmt = $pdo->prepare("SELECT * FROM settings");
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$c = htmlspecialchars($row['site_url']);
$e = filterString($row['contact']);
}
unset($stmt);
} catch (PDOException $e) {
exit($e->getMessage());
}
Thanks for any help
Perhaps keep one connection, rather than opening multiple connections to the Database. You can look into a project PDOEasy that I created to make MVC easy with PDO or use the below static example.
class DB
{
private $_connection;
private static $_instance;
public static function getInstance() {
if(self::$_instance) return self::$_instance;
self::$_instance = new self();
return self::$_instance;
}
private function __construct() {
$this->_connection = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_NAME.'', DB_USERNAME, DB_PASSWORD, array(
PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
));
}
public function getConnection() { return $this->_connection; }
}
Which can be used like so:
$stmt = DB::getInstance()
->getConnection()
->Prepare('SELECT * FROM settings');
$stmt->execute();
foreach($stmt->fetchAll() as $row) {
// ...
}

How to get database stuff by using customized connection

I want to auto save the sql query every time, I found this article, if I do everything by the page it will work, but the problem is, I have master and slave database, therefore I have to connect to database like:
model/Users.php
<?php
class Users extends CI_Model
{
protected $table = 'users';
public $master;
public $slave;
public function __construct()
{
$this->master = $this->load->database('master', true);
$this->slave = $this->load->database('slave', true);
}
public function save($datas)
{
$this->master->insert($this->table, $datas);
return $this->master;
}
}
Then I adjust demo code like:
<?php
class Query_log
{
public function log_query()
{
$ci =& get_instance();
$filepath = APPPATH . 'logs/Query-log-' . date('Y-m-d') . '.php';
$handle = fopen($filepath, "a+");
$times = $ci->master->query_times;
foreach ($ci->master->queries as $key => $query) {
$sql = $query . " \n Execution Time:" . $times[$key];
fwrite($handle, $sql . "\n\n");
}
fclose($handle);
}
}
Of course I got error message
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$master
Filename: hooks/query_log.php
How to make it right?

Symfony2, Keep form data across redirect

How to use session for retrieving data during redirect? I am getting the error message: "exception 'Symfony\Component\Form\Exception\AlreadySubmittedException' with message 'You cannot change the data of a submitted form."
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Controller\UserController.php
/**
* Creates a new User entity.
*
* #Route("/new", name="user_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm(new UserType(), $user);
$form->handleRequest($request);
$session = $this->getRequest()->getSession();
$form->setData(unserialize($session->get('userFilter')));
if ( $form->isSubmitted() && $form->isValid() ) {
$session->set( 'userFilter', serialize($form->getData()) );
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('MeetingBundle::user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
} // public function newAction(Request $request)
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\EventListener\ExceptionListener.php
<?php
namespace MeetingBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
//every time the Kernel throws the kernel.exception event, the function onKernelException() is called.
/* also must create service :
meeting.exception_listener:
class: MeetingBundle\EventListener\ExceptionListener
arguments: [#templating, #kernel, #router]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
*/
class ExceptionListener
{
protected $templating;
protected $kernel;
protected $router;
public function __construct( EngineInterface $templating, $kernel, Router $router)
{
$this->templating = $templating;
$this->kernel = $kernel;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$request=$event->getRequest();
$referer = $event->getRequest()->headers->get('referer');
$msg="";
$excStr=$exception->__toString(); // returns string finally!
$bdup=strpos( $excStr , 'Integrity constraint violation: 1062 Duplicate entry' );
if($bdup) {
$msg=" This username is already taken. Choose another username. ";
}
if(strlen($msg)!=0) {
// flash messsages are displayed in layout.html
$request->getSession()
->getFlashBag()
->add('Error', $msg);
}
$response = new RedirectResponse($referer); // redirect to the error page
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
}

new Facebook SDK 4 throw exception about PHP_SESSION_ACTIVE in laravel

I wanted implement the new facebook API v 4.0.0 on my project laravel.
Setting all the necessary informations and credentials for access to my app, when is time to call the function for the login:
$helper = new FacebookRedirectLoginHelper('http://mywebsite.dev');
$loginUrl = $helper->getLoginUrl();
It throw me an exception
FacebookSDKException 'Session not active, could not store state.'
So I dig in to the SDK class of facebook on that line and there is a check about session precisely this one:
if (session_status() !== PHP_SESSION_ACTIVE) {
throw new FacebookSDKException(
'Session not active, could not store state.'
);
}
Then I didn't know why this happen so i tried to put the same check on a clean route and see the result
Route::get('test',function() {
if (session_status() !== PHP_SESSION_ACTIVE)
{
return "is not active";
}
return "is active";
});
And it return is not active why this happen? in this way I cannot use the new facebook API with laravel?
Sharing how I implemented Facebook SDK V4 on Laravel 4.
Here's what I added on default composer.json
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4" : {
"Facebook\\":"vendor/facebook/php-sdk-v4/src/Facebook/"
}
},
Added Facebook initialization on my index.php, like this :
/*
|--------------------------------------------------------------------------
| Initialized Facebook PHP SDK V4
|--------------------------------------------------------------------------
|
*/
//Initialize
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication(Config::get('facebook.AppId'),Config::get('facebook.AppSecret'));
And for the Session, Laravel doesn't use $_SESSION so you don't need to do session_start at all. For you to be able to use Laravel session on Facebook PHP SDK V4, you need to extend Facebook's FacebookRedirectLoginHelper class.
Here's how how to subclass FacebookRedirectLoginHelper and overwrite Session handling.
class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{
protected function storeState($state)
{
Session::put('state', $state);
}
protected function loadState()
{
$this->state = Session::get('state');
return $this->state;
}
protected function isValidRedirect()
{
return $this->getCode() && Input::has('state')
&& Input::get('state') == $this->state;
}
protected function getCode()
{
return Input::has('code') ? Input::get('code') : null;
}
//Fix for state value from Auth redirect not equal to session stored state value
//Get FacebookSession via User access token from code
public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
{
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
return $params;
}
}
And one more step, you need to do a composer command to regenerate autoload files :
composer dump-autoload -o
Ok, if all goes right, you are now ready to start using the SDK, here's a sample
Here's an excerpt from one of my project classes :
namespace Fb\Insights;
//Facebook Classes
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\FacebookSDKException;
//Our Facebook Controller
use FbController;
class PagePosts extends \Facebook\GraphObject {
/*
Get Page Posts Impression
https://developers.facebook.com/docs/graph-api/reference/v2.0/insights#post_impressions
*/
public static function getPagePostsImpressions($postid = null) {
$fbctrl = new FbController();
$metricNames = array(
'post_impressions',
'post_impressions_unique',
'post_impressions_paid',
'post_impressions_paid_unique',
'post_impressions_fan',
'post_impressions_fan_unique',
'post_impressions_fan_paid',
'post_impressions_fan_paid_unique',
'post_impressions_organic',
'post_impressions_organic_unique',
'post_impressions_viral',
'post_impressions_viral_unique',
'post_impressions_by_story_type',
'post_impressions_by_story_type_unique',
'post_impressions_by_paid_non_paid',
'post_impressions_by_paid_non_paid_unique'
);
$postsInsights = array();
$batch = array();
$limit = $fbctrl->FacebookGraphDateLimit();
//craft our batch API call
for($i=0; $i<count($metricNames); $i++) {
$batch[] = json_encode(array('method' => 'GET','relative_url' => $postid . '/insights/' . $metricNames[$i] . '?since=' . $limit['since'] . '&until=' . $limit['until'] ));
}
$params = array( 'batch' => '[' . implode(',',$batch ) . ']' );
$session = new FacebookSession($fbctrl->userAccessToken);
try {
$res = (new FacebookRequest($session,'POST','/',$params))
->execute()
->getGraphObject();
} catch(FacebookRequestException $ex) {
//log this error
echo $ex->getMessage();
} catch(\Exception $ex) {
//log this error
echo $ex->getMessage();
}
//Collect data
for($i=0; $i<count($batch); $i++) {
$resdata = json_decode(json_encode($res->asArray()[$i]),true);
$fbctrl->batchErrorDataChecker($resdata,$postsInsights,$metricNames[$i]);
}
return $postsInsights;
}
Feel free comment or suggest so I can also improve my code.
Happy coding.
I solve extending that class and overwriting the following 2 methods that require native sessions.
protected function storeState($state)
{
Session::put('facebook.state', $state);
}
protected function loadState()
{
return $this->state = Session::get('facebook.state');
}
I used follow steps using Composer and had problem "Session not active, could not store state" so session_start() fixed my issue.
require_once './vendor/autoload.php';
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
session_start();
FacebookSession::setDefaultApplication('apid', 'appscret');
$helper = new FacebookRedirectLoginHelper("callbackurl", $apiVersion = NULL);
try {
$session = $helper->getSessionFromRedirect();
} catch (FacebookRequestException $ex) {
// When Facebook returns an error
} catch (\Exception $ex) {
// When validation fails or other local issues
}
if (isset($session)) {
$request = new FacebookRequest($session, 'GET', '/me');
$response = $request->execute();
$graphObject = $response->getGraphObject();
var_dump($graphObject);
} else {
echo 'Login with Facebook';
}
To solve problem call session_start php function after to inizialize FacebookRedirectLoginHelper somthing like this:
session_start();
$helper = new FacebookRedirectLoginHelper('http://mywebsite.dev');
$loginUrl = $helper->getLoginUrl();
kaixersoft's answer really saved my bacon a little while ago, and I got everything to work by following his instructions using the custom LaravelFacebookRedirectLoginHelper class. But today I went to do a 'composer update' and for some reason, it broke everything. I've modified kaixersoft's LaravelFacebookRedirectLoginHelper class so that it works now, specifically the isValidRedirect method. Here is the updated class:
class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{
protected function storeState($state)
{
Session::put('state', $state);
}
protected function loadState()
{
$this->state = Session::get('state');
return $this->state;
}
protected function isValidRedirect()
{
$savedState = $this->loadState();
if (!$this->getCode() || !isset($_GET['state'])) {
return false;
}
$givenState = $_GET['state'];
$savedLen = mb_strlen($savedState);
$givenLen = mb_strlen($givenState);
if ($savedLen !== $givenLen) {
return false;
}
$result = 0;
for ($i = 0; $i < $savedLen; $i++) {
$result |= ord($savedState[$i]) ^ ord($givenState[$i]);
}
return $result === 0;
}
protected function getCode()
{
return Input::has('code') ? Input::get('code') : null;
}
//Fix for state value from Auth redirect not equal to session stored state value
//Get FacebookSession via User access token from code
public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
{
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
return $params;
}
}
session_status function is available on (PHP >=5.4.0) version. So if you are using older version of PHP then Please update it Or Just
// change this
if (session_status() !== PHP_SESSION_ACTIVE) {
throw new FacebookSDKException(
'Session not active, could not store state.'
);
}
//into this
if(session_id() === "") {
throw new FacebookSDKException(
'Session not active, could not load state.'
);
}

PHP PDO PGPOOL PGSQL - SQLSTATE[HY000]: General error: 7 no connection to the server

I try to explain the problem I have!!!
I use PDO extension to connect to PostgreSQL through pgpool-II. It works fine within Apache, but from PHP CLI (on the same machine) I receive this PDO error:
SQLSTATE[HY000]: General error: 7 no connection to the server
I have already searched on Google and here, but it seems that no one has ever tried to do this. Does anyone have any idea?
EDIT:
This is the code I use to establish a connection:
include 'manage_db.php';
include_once 'properties.php';
global $properties;
$dsn = 'pgsql:dbname=' . $properties['db_pgpool'] . ';host=localhost;port=' . $properties['port_pgpool'];
try{
$mgmtDb = new ManageDb($dsn, $properties['username_pgpool'], $properties['password_pgpool']);
} catch (Exception $e) {
echo 'PDO - Caught exception: ', $e->getMessage(), "\n";
}
ManageDB is my own class that implements some utility functions as well as create the database connection:
class ManageDb {
var $db;
function ManageDb($dsn, $username, $password){
$this->db = new PDO($dsn, $username, $password);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
....
Try this
config.database.php
<?php
class DatabaseConfig {
const DBNAME = 'dbname';
const HOST = '123.1.233.123';
const USER = 'mysuperuser';
const PASSWORD = 'mysupperparrword';
const PORT = 5432;
}
?>
class.database.php
<?php
include('config.database.php');
class Database {
protected static $instance = null;
final private function __construct() {}
final private function __destruct() {
self::$instance = null;
}
final private function __clone() {}
public static function getInstance() {
if (self::$instance === null) {
try {
self::$instance = new PDO(
'pgsql:host=' . DatabaseConfig::HOST .
';port=' . DatabaseConfig::PORT .
';dbname=' . DatabaseConfig::DBNAME .
';user=' . DatabaseConfig::USER .
';password=' . DatabaseConfig::PASSWORD
);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
} catch (PDOException $e) {
die('Database connection could not be established.');
}
}
return self::$instance;
}
public static function __callStatic($method, $args) {
return call_user_func_array(array(self::instance(), $method), $args);
}
}
?>