Workerman closes suddnly after send message - php

I am using workerman PHP library to create WebSocket server.
require dirname(__DIR__) . '/vendor/autoload.php';
use Workerman\Worker;
// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:8047");
// 4 processes
$ws_worker->count = 4;
// Emitted when new connection come
$ws_worker->onConnect = function($connection)
{
echo "New connection\n";
};
// Emitted when data received
$ws_worker->onMessage = function($connection, $data)
{
var_dump($data);
// Send hello $data
$connection->send('hello ' . $data);
};
// Emitted when connection closed
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// Run worker
Worker::runAll();
everything works fine. So I use this class to send message web socket server:
// https://github.com/Textalk/websocket-php
$client = new Client('ws://127.0.0.1:8047/');
$client->send('test !');
Sometimes output this error:
// Validate response.
if (!preg_match('#Sec-WebSocket-Accept:\s(.*)$#mUi', $response, $matches)) {
$address = $scheme . '://' . $host . $path_with_query;
throw new ConnectionException(
"Connection to '{$address}' failed: Server sent invalid upgrade response:\n"
. $response
);
}
If restart server it works again ... but every time after send connection is closes. I can't understand why connection closes.
PHP 7.2.0 (cli) (built: Nov 28 2017 23:48:49) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies

Related

Cannot get SOAP response from world server

When using the following connection script:
<?php
ini_set('default_socket_timeout', 120);
$soap_connection_info = array(
'soap_uri' => 'urn:AC',
'soap_host' => '127.0.0.1',
'soap_port' => '7878',
'account_name' => 'acore',
'account_password' => 'password'
);
function RemoteCommandWithSOAP($username, $password, $COMMAND)
{
global $soap_connection_info;
$result = '';
try {
$conn = new SoapClient(NULL, array(
'location' => 'http://' . $soap_connection_info['soap_host'] . ':' . $soap_connection_info['soap_port'] . '/',
'uri' => $soap_connection_info['soap_uri'],
'style' => SOAP_RPC,
'login' => $username,
'password' => $password,
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
));
$result = $conn->executeCommand(new SoapParam($COMMAND, 'command'));
unset($conn);
} catch (Exception $e) {
$result = "\nHave error on soap!\n" . $e . "\n";
if (strpos($e, 'There is no such command') !== false) {
$result = 'There is no such command!';
}
}
return $result;
}
echo RemoteCommandWithSOAP($soap_connection_info['account_name'], $soap_connection_info['account_password'], ".server info");
?>
With the world server running and listening to port 7878, I get:
local-iMac $ php test.php
Have error on soap!
SoapFault exception: [HTTP] Error Fetching http headers in /Users/dan/dev/test.php:26
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://127.0.0....', 'urn:AC#executeC...', 1, false)
#1 /Users/dan/dev/test.php(26): SoapClient->__call('executeCommand', Array)
#2 /Users/dan/dev/test.php(39): RemoteCommandWithSOAP('acore', 'password', '.server info')
#3 {main}
I know error fetching headers points to a possible timeout when waiting for a response but this error comes up instantly as if there was no wait. However I added in the ini_set('default_socket_timeout', 120); in my script just to be sure.
My worldserver.conf:
# - the DB hostname will be the name of the database docker container
LoginDatabaseInfo = "ac-database;3306;root;password;acore_auth"
WorldDatabaseInfo = "ac-database;3306;root;password;acore_world"
CharacterDatabaseInfo = "ac-database;3306;root;password;acore_characters"
# Add more configuration overwrites by copying settings from worldserver.conf.dist
LogLevel = 5
Appender.File=2,5,7,debug.log,w
Logger.network.soap=5,File
Logger.server.worldserver=5,File
# Disable idle connections automatic kick since it doesn't work well on macOS + Docker
CloseIdleConnections = 0
Updates.EnableDatabases = 1
Death.SicknessLevel = -10
SOAP.Enabled = 1
SOAP.IP = "127.0.0.1"
SOAP.Port = 7878
And my docker-compose is unchanged:
https://github.com/azerothcore/azerothcore-wotlk/blob/master/docker-compose.yml
Interestingly if I down the world container I will get a different response as if it was connecting when it was up.
local-iMac $ php test.php
Have error on soap!
SoapFault exception: [HTTP] Could not connect to host in /Users/dan/dev/test.php:26
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://127.0.0....', 'urn:AC#executeC...', 1, false)
#1 /Users/dan/dev/test.php(26): SoapClient->__call('executeCommand', Array)
#2 /Users/dan/dev/test.php(39): RemoteCommandWithSOAP('acore', 'password', '.server info')
#3 {main}
Also I enabled worldserver logs to see what was going on in SOAP:
2021-09-23_20:41:17 INFO [server.worldserver] > Using configuration file /azerothcore/env/dist/etc/worldserver.conf
2021-09-23_20:41:17 INFO [server.worldserver] > Using SSL version: OpenSSL 1.1.1f 31 Mar 2020 (library: OpenSSL 1.1.1f 31 Mar 2020)
2021-09-23_20:41:17 INFO [server.worldserver] > Using Boost version: 1.71.0
2021-09-23_20:41:17 INFO [server.worldserver]
2021-09-23_20:41:17 INFO [server.worldserver] Process priority class set to -15
2021-09-23_20:41:31 INFO [network.soap] ACSoap: bound to http://127.0.0.1:7878
Also I know container is correctly listening to the port:
f166a28ffdf5 acore/ac-wotlk-worldserver-local:master "./acore.sh run-worl…" 3 weeks ago Up 48 minutes 0.0.0.0:7878->7878/tcp, :::7878->7878/tcp, 0.0.0.0:8085->8085/tcp, :::8085->8085/tcp azerothcore-wotlk_ac-worldserver_1
Some stats on my local:
MacOS Mojave 10.14.6
local-iMac $ docker -v
Docker version 20.10.7, build f0df350
local-iMac $ php -v
PHP 8.0.10 (cli) (built: Aug 26 2021 15:37:37) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.10, Copyright (c) Zend Technologies
with Zend OPcache v8.0.10, Copyright (c), by Zend Technologies
Docker acts like a DHCP server and assigns IP's to the containers. You need to check for what the 'local' IP is and that means 'local' to docker.
docker inspect <containerID> | grep IPAddress
That is the ip you need to bind to in your config.
SOAP.Enabled = 1
SOAP.IP = "172.19.0.3"
SOAP.Port = 7878

View JSON API value on php file

I'm trying to create a php script to display only the "credit" value of the account 491027679-102 but it does not work, I get a white screen. Can you help me solve this problem?
This is the script I did, where I drew?
<?php
$url = 'https://www.vohippo.com/it/vohippo/user/ApiWhsGetSubList?email=mail#example.com&apikey=123';
$content = file_get_contents($url);
$apiResult = json_decode($content);
($apiResult['status'] !== 'ok') &&
trigger_error('Unexpected API Result');
empty(($account = array_filter($apiResult['result'], function($item) {
return $item['account'] === '491027679-102';
}))) && trigger_error('Account not found.');
echo $account[0]['credit'];
?>
If you already know the index of the parent array for the credit, you can do it as above echo $account[0]['credit'];.
If you don't know the index of the parent and it changes everytime in the $account variable, you should loop through the array.
Instead of using echo $account[0]['credit'];, you should loop through the array:
foreach ($account as $key => $value) {
echo $account[$key]['credit'];
}
Your script:
<?php
// https://stackoverflow.com/questions/54390848/view-json-api-value-on-php-file
$url = 'https://www.vohippo.com/it/vohippo/user/ApiWhsGetSubList?email=webmasterlertux#gmail.com&apikey=4c62479846b0aea59ac007f3a283b581';
$content = file_get_contents($url);
$apiResult = json_decode($content);
($apiResult['status'] !== 'ok') && trigger_error('Unexpected API Result');
empty(($account = array_filter($apiResult['result'], function($item) {
return $item['account'] === '491027679-102';
}))) && trigger_error('Account not found.');
echo $account[0]['credit'];
?>
My php version:
php-fpm at 87a5be43419e in /var/www/html
$ php --version
PHP 7.2.4 (cli) (built: Apr 5 2018 00:37:24) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
Running your script:
$ php question-54390848.php
Fatal error: Uncaught Error: Cannot use object of type stdClass as array in /var/www/html/question-54390848.php:9
Stack trace:
#0 {main}
thrown in /var/www/html/question-54390848.php on line 9
The error is in line 9 because you try to access an array when you an object, because in line 7 json_decode($content) gives you an object, but to get an array you need to do `json_decode($content, true).
Lets' fix it:
<?php
// https://stackoverflow.com/questions/54390848/view-json-api-value-on-php-file
$url = 'https://www.vohippo.com/it/vohippo/user/ApiWhsGetSubList?email=webmasterlertux#gmail.com&apikey=4c62479846b0aea59ac007f3a283b581';
$content = file_get_contents($url);
// Adding `true` to enable decoding to an array
$apiResult = json_decode($content, true);
($apiResult['status'] !== 'ok') && trigger_error('Unexpected API Result');
$account = [];
empty(($account = array_filter($apiResult['result'], function($item) {
return $item['account'] === '491027679-102';
}))) && trigger_error('Account not found.');
// using array_filter will return the array entries as they have been matched,
// thus your match happens in the array entry with key `1`, but you try to
// access the entry `0` in the echo statement.
// so using array_values will return all values in the array indexed from key `0`.
$account = array_values($account);
echo $account[0]['credit'];
?>
Another fix was needed in order you can access the $account[0] in your echo statement. Please read the comments in the code.
Running your script again:
php-fpm at 87a5be43419e in /var/www/html
$ php question-54390848.php
0.0000
NOTE: Your script needs to have more checks for errors with the response and when accessing the $account array.
SECURITY ALERT
You have published the API KEY in your question:
$url = 'https://www.vohippo.com/it/vohippo/user/ApiWhsGetSubList?email=webmasterlertux#gmail.com&apikey=4c62479846b0aea59ac007f3a283b581';
Now everyone can access this service in your behalf and if is a paid one you will be the one paying the bill.
Please reset this API KEY immediately and get a new one
API KEYS best practice is to be sent in the header

Moodle REST APIs failing intermittently and returning 500 (Internal Server Error)

Moodle REST APIs failing intermittently and returning 500 (Internal Server Error)
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.30-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies
<?php
error_reporting(-1); // reports all errors
ini_set("display_errors", "1"); // shows all errors
ini_set("log_errors", 1);
ini_set("error_log", "php-error.log");
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* #package local_lingk
* #copyright (C) 2018 Lingk Inc (http://www.lingk.io)
* #license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../config.php';
//require_once '../lib/moodlelib.php';
// require_once($CFG->dirroot.'/lib/moodlelib.php');
require_once($CFG->libdir.'/moodlelib.php');
require_once 'src/Mandrill.php'; //Not required with Composer
global $DB, $CFG, $SESSION, $USER;
$CFG = new stdClass();
$CFG->dataroot = '/usr/src/moodle/moodledata';
$CFG->cookiename = 'MoodleSession';
$USER = new stdClass();
$USER->id = -10;
$USER->email = 'emailed';
$USER->firstname = 'Do not reply to this email';
$USER->username = 'noreply';
$USER->lastname = '';
$USER->confirmed = 1;
$USER->suspended = 0;
$USER->deleted = 0;
$USER->picture = 0;
$USER->auth = 'manual';
$USER->firstnamephonetic = '';
$USER->lastnamephonetic = '';
$USER->middlename = '';
$USER->alternatename = '';
$USER->imagealt = '';
$USER->maildisplay = 1;
$USER->emailstop = 1;
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Credentials: true");
header('Content-Type: application/json');
header("HTTP/1.0 200 Successfull operation");
// echo '=============+++++++';exit;
$wsfunction = $_POST['wsfunction'];
// print_r($record);exit;
// $client_id = $_POST['client_id'];
// $client_secret = $POST['client_secret'];
// $device_id = $POST['device_id'];
$response = array();
I tried changing apache config and mysql config but APIs are failing intermittently. It works 2 times and fails on 3rd and sometimes succeeds thrice and fails on fourth attempt. Am I missing any configuration or moodle setting?

PHP SSH Warning: stream_get_contents(): Failure 'would block' (-9)"

I got a Warning from my code
Warning: stream_get_contents(): Failure 'would block' (-9) in /var/www/html/public_html/site.php on line 51
It is thrown only at this command:
service apache2 reload
My code is:
public function exec( $cmd, &$output = '' ) {
$connection = ssh2_connect( '*********', 22 );
ssh2_auth_password( $connection, '********', '******+*' );
$stream = ssh2_exec( $connection, $cmd );
$errorStream = ssh2_fetch_stream( $stream, SSH2_STREAM_STDERR );
stream_set_blocking( $errorStream, TRUE );
stream_set_blocking( $stream, TRUE );
var_dump( $cmd );
echo '<br>';
$output = stream_get_contents( $stream );
$error = stream_get_contents( $errorStream );
if ( strlen( $error ) > 0 ) {
var_dump( $error );
}
fclose( $errorStream );
fclose( $stream );
}
The code is starting at line 39, the warning is on the line with the
$output = stream_get_contents( $stream );
Any solution against the warning ?
EDIT
The function is in a class that is a part of a webinterface to manage the vhosts
Some Informations about the Server:
Apache
root#development:/# apache2 -v
Server version: Apache/2.4.10 (Debian)
Server built: Aug 28 2015 16:28:08
PHP
root#development:/# php -v
PHP 5.6.13-0+deb8u1 (cli) (built: Sep 7 2015 13:38:37)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
OS
root#development:/# uname -a
Linux development 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04) x86_64 GNU/Linux
root#development:/# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.2 (jessie)
Release: 8.2
Codename: jessie

PHPStorm Debug CLI to HTTP Request

I am trying to debug a Laravel artisan command, executed via CLI, which in turn calls an external endpoint (via Guzzle).
Both the original app and the external endpoint are available locally, open in PHPStorm as two separate projects.
I'm able to debug the CLI command by running this command in terminal:
export XDEBUG_CONFIG="remote_enable=1 remote_mode=req remote_port=9000 remote_host=127.0.0.1 remote_connect_back=0"
(or for windows):
set XDEBUG_CONFIG="remote_enable=1 remote_mode=req remote_port=9000 remote_host=127.0.0.1 remote_connect_back=0"
As illustrated on PHPStorm docs, you can execute an external script by passing a debug query string:
$debuggingQuerystring = '';
if (isset($_GET['XDEBUG_SESSION_START'])) { // xdebug
$debuggingQuerystring = 'XDEBUG_SESSION_START=' . $_GET['XDEBUG_SESSION_START'];
}
if (isset($_COOKIE['XDEBUG_SESSION'])) { // xdebug (cookie)
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
if (isset($_GET['start_debug'])) { // zend debugger
$debuggingQuerystring = 'start_debug=' . $_GET['start_debug'];
}
$personJson = file_get_contents('http://127.0.0.1:778/backend.php?' . $debuggingQuerystring);
The current problem that when executed via CLI, the $debugQueryString is empty. What do we pass along and how to the external url which will allow debugging on the second project?
$client = new Guzzle\Http\Client($this->webhook_url);
$response = $client->post('', [], $this->params)->send();
$code = $response->getStatusCode();
This was easier than I thought.
$debuggingQuerystring = '';
if (isset($_GET['XDEBUG_SESSION_START'])) { // xdebug
$debuggingQuerystring = 'XDEBUG_SESSION_START=' . $_GET['XDEBUG_SESSION_START'];
}
if (isset($_COOKIE['XDEBUG_SESSION'])) { // xdebug (cookie)
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
if (isset($_GET['start_debug'])) { // zend debugger
$debuggingQuerystring = 'start_debug=' . $_GET['start_debug'];
}
if(empty($debuggingQuerystring))
{
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
$this->debugString = $debuggingQuerystring;
And then the url call:
$client = new Guzzle\Http\Client($this->webhook_url);
$response = $client->post('?' . $this->debugString, [], $this->final_data)->send();
$code = $response->getStatusCode();

Categories