I'm creating this website which lists minecraft servers. Basically I'm trying to ping all these servers as they are displayed. Solving this problem with php doesn't quite solve it for me, pinging all the servers takes time, and I know javascript can execute multiple "pings" at the same time. How would I do this?
The PHP code I'm using now:
class minecraft_server
{
private $address;
private $port;
public function __construct($address, $port = 25565){
$this->address = $address;
$this->port = $port;
}
public function get_ping_info(&$info){
$starttime = microtime(true);
$socket = #fsockopen($this->address, $this->port, $errno, $errstr, 1.0);
$stoptime = microtime(true);
$ping = round(($stoptime-$starttime)*1000);
if ($socket === false){
return false;
}
fwrite($socket, "\xfe\x01");
$data = fread($socket, 256);
if (substr($data, 0, 1) != "\xff"){
return false;
}
if (substr($data, 3, 5) == "\x00\xa7\x00\x31\x00"){
$data = explode("\x00", mb_convert_encoding(substr($data, 15), 'UTF-8', 'UCS-2'));
}else{
$data = explode('ยง', mb_convert_encoding(substr($data, 3), 'UTF-8', 'UCS-2'));
}
if (count($data) == 3){
$info = array(
'version' => '1.3.2',
'motd' => $data[0],
'players' => intval($data[1]),
'max_players' => intval($data[2]),
'ping' => $ping
);
}else{
$info = array(
'version' => $data[0],
'motd' => $data[1],
'players' => intval($data[2]),
'max_players' => intval($data[3]),
'ping' => $ping
);
}
return true;
}
}
And you call the function with:
$server = new minecraft_server(IP, PORT);
if (!$server->get_ping_info($info)){
echo "Offline";
}else{
print_r($info);
}
How would I create a similar thing in javascript?
In your place, I probably would have set up a script that, when called, pings the selected server and prints a parse-able result, then call that script using Ajax whenever a ping needs to be sent.
Related
I want to check if a quake3 game server is online or offline. If offline then echo 'Server is offline' if online then echo 'Server is online'.
I'm using this library:
As you see in the library there's already an isOnline function I think that's for server is online or no?! but I don't know how to output that.
Calling the game server data's:
<?php
include 'test/GameServerQuery.php';
$data = GameServerQuery::queryQuake3('1.1.1.1', 28960);
echo 'Hostname: ' . $data['sv_hostname'] . '<br />';
echo 'Players online: ' . $data['sv_maxclients'] . '<br />'; /// How can I count online players / maxclients? ex.: 0/20
echo 'Punkbuster: ' . $data['sv_punkbuster'] . '<br />';
?>
Here is relevant code from the library (in case the link should die or change):
public static function isOnline ($host, $port, $type)
{
if ($type == 'minecraft') { // No need for the full ping
return #fclose (#fsockopen ( $host , $port , $err , $errstr , 2 ));
}
if (method_exists('GameServerQuery', 'query'.$type)) {
return self::{'query'.$type}($host , $port);
}
return #fclose (#fsockopen ( $host , $port , $err , $errstr , 2 ));
}
public static function queryQuake3($host, $port)
{
$reponse = self::ping($host, $port, "\xFF\xFF\xFF\xFFgetstatus\x00");
if ($reponse === false || substr($reponse, 0, 5) !== "\xFF\xFF\xFF\xFFs") {
return false;
}
$reponse = substr($reponse, strpos($reponse, chr(10))+2);
$info = array();
$joueurs = substr($reponse, strpos($reponse,chr(10))+2);
$reponse = substr($reponse, 0, strpos($reponse, chr(10)));
while($reponse != ''){
$info[self::getString($reponse, '\\')] = self::getString($reponse, '\\');
}
if (!empty($joueurs)) {
$info['players'] = array();
while ($joueurs != ''){
$details = self::getString($joueurs, chr(10));
$info['players'][] = array('frag' => self::getString($details, ' '),
'ping' => self::getString($details, ' '),
'name' => $details);
}
}
return $info;
}
private static function ping($host, $port, $command)
{
$socket = #stream_socket_client('udp://'.$host.':'.$port, $errno, $errstr, 2);
if (!$errno && $socket) {
stream_set_timeout($socket, 2);
fwrite($socket, $command);
$buffer = #fread($socket, 1500);
fclose($socket);
return $buffer;
}
return false;
}
private static function getString(&$chaine, $chr = "\x00")
{
$data = strstr($chaine, $chr, true);
$chaine = substr($chaine, strlen($data) + 1);
return $data;
}
It's a static function, just like the one you're already calling. Something like this would do the job, I think:
$result = GameServerQuery::isOnline('1.1.1.1', 28960, "Quake3");
print_r($result);
That will show you what result you get back. I suspect it will be the same as the queryQuake3 function actually, because if you specify "Quake3" as the last parameter, the isOnline function will simply call the "queryQuake3" function and pass the result back directly.
So, the function should return either false if the server is offline or otherwise unresponsive, and either true, or a more complex dataset if it's online.
So in fact I think you could write:
$result = GameServerQuery::isOnline('1.1.1.1', 28960, "Quake3");
if ($result === false) {
echo "Server is offline";
}
else {
echo "Server is online";
}
I try to write code for email verify like that
But i have one problem, 25 port not connect with any mail server
My code like that
Example.php
<?php
require('smtp-validate-email.php');
$from = 'harsukh21#gmail.com'; // for SMTP FROM:<> command
$emails = 'harsukh#gmail.com';
$validator = new SMTP_Validate_Email($emails, $from);
$smtp_results = $validator->validate();
echo "<pre>";print_r($smtp_results);exit;
smtp-validate-email.php
<?php/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. *//** * Description of EmailValidation * * #author Harsukh Makwana <harsukh21#gmail.com> */class EmailValidation{ public $hellodomain = 'itsolutionstuff.com'; public $mailfrom = 'harsukh21#gmail.com'; public $rcptto; public $mx; public $ip; public function __construct() { $this->ip = '192.168.2.14'; } public function checkEmail($email = null) { $this->rcptto = $email; $array = explode('#', $this->rcptto); $dom = $array[1]; if (getmxrr($dom, $mx)) { $this->mx = $mx[rand(0, count($mx) - 1)]; return $this->processRange($this->ip); } return false; } private function asyncRead($sock) { $read_sock = array($sock); $write_sock = NULL; $except_sock = NULL; if (socket_select($read_sock, $write_sock, $except_sock, 5) != 1) { return FALSE; } $ret = socket_read($sock, 512); return $ret; } private function smtpConnect($mta, $src_ip) { $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($sock == FALSE) { return array(FALSE, 'unable to open socket'); } if (!socket_bind($sock, $src_ip)) { return array(FALSE, 'unable to bind to src ip'); } $timeout = array('sec' => 10, 'usec' => 0); socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, $timeout); socket_set_nonblock($sock); var_dump(#socket_connect($sock, $mta, 25));exit; #socket_connect($sock, $mta, 25); $ret = $this->asyncRead($sock); if ($ret === FALSE) { return array(FALSE, 'inital read timed out'); } if (!preg_match('/^220/', $ret)) { // Not a good connection. return array(FALSE, $ret); } // Now do the EHLO. socket_write($sock, "HELO ".$this->hellodomain."\r\n"); $ret = $this->asyncRead($sock); if ($ret === FALSE) { return array(FALSE, 'ehlo timed out'); } if (!preg_match('/^250/', $ret)) { // Not a good response. return array(FALSE, $ret); } // Now MAIL FROM. socket_write($sock, "MAIL FROM:<".$this->mailfrom.">\r\n"); $ret = $this->asyncRead($sock); if ($ret === FALSE) { return array(FALSE, 'from timed out'); } if (!preg_match('/^250/', $ret)) // Not a good response. return array(FALSE, $ret); // Now RCPT TO. socket_write($sock, "RCPT TO:<".$this->rcptto.">\r\n"); $ret = $this->asyncRead($sock); if ($ret === FALSE) { return array(FALSE, 'rcpt to timed out'); } if (!preg_match('/^250/', $ret)) { // Not a good response. return array(FALSE, $ret); } // All good. socket_close($sock); return array(true, $ret); } private function processRange($ip) { list($ret, $msg) = $this->smtpConnect($this->mx, $ip); $msg = trim($msg); return $ret; }}
Output
Array
(
[harsukh#gmail.com] =>
[domains] => Array
(
[gmail.com] => Array
(
[users] => Array
(
[0] => harsukh
)
[mxs] => Array
(
[gmail-smtp-in.l.google.com] => 5
[alt1.gmail-smtp-in.l.google.com] => 10
[alt2.gmail-smtp-in.l.google.com] => 20
[alt3.gmail-smtp-in.l.google.com] => 30
[alt4.gmail-smtp-in.l.google.com] => 40
[gmail.com] => 0
)
)
)
)
Here harsukh#gmail.com is a already exist, But i getting null responce
can i use another port for mail server?
You can't use a port that's already in use. So probebly there is already an email server on the same machine where you are running your code.
can i use another port for mail server?
If you plan to use only clients written by yourself, so that you can change the port to which they send data, that can be acceptable, otherwise no.
What my problem is that I can not send array to solr machine in order to update. I am using codeigniter as a framework and here is my code:
$solrData = array();
$solrData['id'] = $this->data['profil_data']['id'];
$solrData['site'] = $this->data['profil_data']['site'];
$solrData['url_Domain'] = $this->data['profil_data']['url_Domain'];
$solrData['url_Page'] = $this->data['profil_data']['url_Page'];
$solrData['url_Profil'] = $this->data['profil_data']['url_Profil'];
$solrData['scr_Kobi_Rank'] = $this->data['profil_data']['scr_Kobi_Rank'];
$solrData['scr_A'] = $this->data['profil_data']['scr_A'];
$solrData['scr_B'] = $this->data['profil_data']['scr_B'];
$solrData['scr_C'] = $this->data['profil_data']['scr_C'];
$solrData['scr_D'] = $this->data['profil_data']['scr_D'];
$solrData['loc_City'] = $this->input->post('plakano');
$solrData['loc_Lat_Lon'] = $this->input->post('loc_Lat_Lon');
$solrData['com_Category'] = explode(',', $this->input->post('category'));
$urunData = $this->input->post('urun_list');
foreach($urunData as $row)
{
$ontoData = $this->m_onto->getOntoDataByOntoDataId($row);
$solrData['com_Products'][] = $ontoData['baslik'];
}
$hizmetData = $this->input->post('hizmet_list');
foreach($hizmetData as $row)
{
$ontoData = $this->m_onto->getOntoDataByOntoDataId($row);
$solrData['com_Services'][] = $ontoData['baslik'];
}
$solrData['com_Type'] = $this->input->post('sirketturu');
$solrData['com_Description'] = $this->input->post('description');
$solrData['com_Title_Selected'] = $this->input->post('title');
$solrData['com_Title_Long'] = $this->data['profil_data']['com_Title_Long'];
$solrData['crm_Tel'] = $this->input->post('tel');
$solrData['crm_Fax'] = $this->input->post('fax');
$solrData['crm_Email'] = $this->input->post('email');
$this->solr->updateSolrProfilData($solrData);
And solr process:
public function updateSolrProfilData($arrData)
{
if(count($arrData) == 0)
return FALSE;
$solrClientOptions = $this->solrClientOptionsYazProfil;
$solrClientOptionsCommit = $this->solrClientOptionsYazProfilCommit;
$solrClient = new SolrClient($solrClientOptions);
$solrDoc = new SolrInputDocument();
foreach($arrData as $firmaField => $firmaValue)
{
if(! is_array($firmaValue))
{
$solrDoc->addField($firmaField, $firmaValue);
}
else
{
foreach($firmaValue as $firmaField2 => $firmaValue2)
{
if($firmaValue2 != '')
{
$solrDoc->addField($firmaField, $firmaValue2);
}
}
}
}
try {
$this->_solrCommit($solrClientOptionsCommit);
} catch (Exception $e) {
echo $e->getMessage();
}
}
Solr Commit function:
private function _solrCommit($solrArr)
{
$urlCommit = 'http://' . $solrArr['hostname'] . ":" . $solrArr['port'] . '/' . $solrArr['path'] . "/update?stream.body=%3Ccommit/%3E&wt=json";
$output = file_get_contents($urlCommit);
$outputArr = json_decode($output, TRUE);
if ($outputArr['responseHeader']['status'] === 0)
return TRUE;
else
return FALSE;
}
And that is the options:
private $solrClientOptionsYazProfilCommit = array(
'hostname' => SOLR_HOST_YAZ,
'login' => '',
'password' => '',
'port' => SOLR_PORT,
'path' => 'solr/collection1'
);
Altough try-catch returns no error, the data can not be updated. Moreover, code sends solr commit succesfully. I checked the url but it is in correct form. What is wrong in here?
Dont use PHP/Pecl solr libs. If you can access solr via a URL then you should just use PHP and CURL:
static function doCurl($url, $username = null, $password = null) {
if (!function_exists('curl_init')) {
// throw error
}
$ch = curl_init();
$opts = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_TIMEOUT => 120,
CURLOPT_FAILONERROR => 1,
CURLOPT_HTTPAUTH => CURLAUTH_ANY
);
if ($password != null && $username != null) {
$opts[CURLOPT_USERPWD] = "$username:$password";
}
curl_setopt_array($ch, $opts);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
usage is:
doCurl("http://hostNameHere:8983/solr/select/?q=solr&start=0&rows=10&indent=on", "user", "pass");
Your issue is that you are never issuing a command to Solr to add the document that you have built to your index. You are only issuing the commit command, which is executing successfully.
Since you are using PHP, I would recommend using the PHP SolrClient. This will save you from having to manually write all of the functions (add, delete, commit, etc.) yourself. In this case, you would need to call the addDocument function.
I am trying to establish P2P between two PHP daemon deployed on machines in different network (both behind NAT). I searched around for NAT traversal using PHP on Google and seems like their is no existing solution for this in PHP.
Does anyone know about a solution/library to work this around with PHP?
If anybody else is looking for an answer, here is a simple class that does the job:
<?php
class STUNClient
{
private $socket;
public function __construct()
{
//stun.l.google.com
$this->setServerAddr("66.102.1.127", 19302);
$this->createSocket();
}
public function setServerAddr($host, $port = 3478)
{
$this->serverIP = $host;
$this->serverPort = $port;
}
public function createSocket()
{
$this->socket = socket_create(AF_INET, SOCK_DGRAM, getprotobyname("udp"));
socket_set_nonblock($this->socket);
}
public function getPublicIp()
{
$msg = "\x00\x01\x00\x08\xc0\x0c\xee\x42\x7c\x20\x25\xa3\x3f\x0f\xa1\x7f\xfd\x7f\x00\x00\x00\x03\x00\x04\x00\x00\x00\x00";
$numberOfBytesSent = socket_sendto($this->socket, $msg, strlen($msg), 0, $this->serverIP, $this->serverPort);
$st = time();
while (time() - $st < 1) {
socket_recvfrom($this->socket, $data, 32, 0, $remoteIP, $remotePort);
if (strlen($data) < 32) {
continue;
}
break;
}
try {
$info = unpack("nport/C4s", substr($data, 26, 6));
$ip = sprintf("%u.%u.%u.%u", $info["s1"], $info["s2"], $info["s3"], $info["s4"]);
$port = $info['port'];
return [
'ip' => $ip,
'port' => $port
];
} catch (Exception $e) {
return [
'ip' => "0.0.0.0",
'port' => "0"
];
}
}
}
It's used like this:
$sc = new STUNClient;
print_r( $sc->getPublicIp() ); //prnints out the public ip and port
I'm having a problem with curl_multi_*, I want to create a class / function that receives, lets say 1000 URLs, and processes all those URLs 5 at a time, so when a URL finishes downloading it will allocate the now available slot to a new URL that hasn't been processed yet.
I've seen some implementations of curl_multi, but none of them allows me to do what I want, I believe the solution lies somewhere in the usage of curl_multi_select but the documentation isn't very clear and the user notes don't help much.
Can anyone please provide me with some examples how I can implement such a feature?
Here's one way to do it. This script will fetch any number of urls at a time, and add a new one as each is finished (so it's always fetching $maxConcurrent pages).
$sites = array('http://example.com', 'http://google.com', 'http://stackoverflow.com');
$concurrent = 2; // Any number.
$mc = new MultiCurl($sites, $concurrent);
$mc->process();
echo '</pre>';
class MultiCurl
{
private $allToDo;
private $multiHandle;
private $maxConcurrent = 2;
private $currentIndex = 0;
private $info = array();
private $options = array(CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
CURLOPT_TIMEOUT => 3);
public function __construct($todo, $concurrent)
{
$this->allToDo = $todo;
$this->maxConcurrent = $concurrent;
$this->multiHandle = curl_multi_init();
}
public function process()
{
$running = 0;
do {
$this->_addHandles(min(array($this->maxConcurrent - $running, $this->_moreToDo())));
while ($exec = curl_multi_exec($this->multiHandle, $running) === -1) {
}
curl_multi_select($this->multiHandle);
while ($multiInfo = curl_multi_info_read($this->multiHandle, $msgs)) {
$this->_showData($multiInfo);
curl_multi_remove_handle($this->multiHandle, $multiInfo['handle']);
curl_close($multiInfo['handle']);
}
} while ($running || $this->_moreTodo());
return $this;
}
private function _addHandles($num)
{
while ($num-- > 0) {
$handle = curl_init($this->allToDo[$this->currentIndex]);
curl_setopt_array($handle, $this->options);
curl_multi_add_handle($this->multiHandle, $handle);
$this->info[$handle]['url'] = $this->allToDo[$this->currentIndex];
$this->currentIndex++;
}
}
private function _moreToDo()
{
return count($this->allToDo) - $this->currentIndex;
}
private function _showData($multiInfo)
{
$this->info[$multiInfo['handle']]['multi'] = $multiInfo;
$this->info[$multiInfo['handle']]['curl'] = curl_getinfo($multiInfo['handle']);
//print_r($this->info[$multiInfo['handle']]);
$content = curl_multi_getcontent($multiInfo['handle']);
echo $this->info[$multiInfo['handle']]['url'] . ' - ' . strlen($content) . ' bytes<br />';
//echo htmlspecialchars($content);
}
}