On a very busy PHP server, I am trying to get a global counter going and thought shared memory would be the way to go. Ideally I would use APC
apc_add('counter',1);
apc_inc('counter',1);
var_dump(apc_fetch('counter'));
except that it is not available on the servers and I am restricted to what is available. The servers do have shmop so tried to get that to work, however it seems to be session specific. Is there anything else that could be used?
The shmop code I tried:
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, "c", 0644, 8);
$shm_data = shmop_read($shm_id, 0, 8);
$shm_data = shmop_read($shm_id, 0, 8);
var_dump($shm_data);
if (empty($shm_data)) {
//counter has not been set
$shm_bytes_written = shmop_write($shm_id, 0, 1);
} else {
$shm_bytes_written = shmop_write($shm_id, (int)$shm_data + 1, 0);
}
$shm_data = shmop_read($shm_id, 0, 8);
var_dump($shm_data);
Related
I'm using some API to get a remote server's info by sending a packet with fwrite() and then read the returned value by fread(). Most of the times it works properly, but every 5 to 10 times, it will return an empty string from fread(). This is the code I use:
public function getInfo()
{
#fwrite($this->rSocket, $this->createPacket('i'));
$inforead = fread($this->rSocket, 999);
if(strlen($inforead) >= 28)
{
$inforead = substr($inforead, 11);
$aDetails['password'] = (integer) ord(substr($inforead, 0, 1));
$aDetails['players'] = (integer) $this->toInteger(substr($inforead, 1, 2));
$aDetails['maxplayers'] = (integer) $this->toInteger(substr($inforead, 3, 2));
$inforead = substr($inforead, 5);
$iStrlen = ord(substr($inforead, 0, 4));
if(!$iStrlen) return -1;
$aDetails['hostname'] = (string) substr($inforead, 4, $iStrlen);
$inforead = substr($inforead, 4+$iStrlen);
$iStrlen = ord(substr($inforead, 0, 4));
$aDetails['gamemode'] = (string) substr($inforead, 4, $iStrlen);
$inforead = substr($inforead, 4+$iStrlen);
$iStrlen = ord(substr($inforead, 0, 4));
$aDetails['mapname'] = (string) substr($inforead, 4, $iStrlen);
}
return $aDetails;
}
I also debugged fwrite() and it seems it returns the number of bytes written and not false, meaning the error wasn't in fwrite(). Is the problem with my code or with the server failing to provide the info?
The constructor opens the socket, so it won't be visible here.
I've just encountered a strange stream socket situation, my fread code always returned empty string.
I replaced fread by stream_get_contents and problem solved
Alright i have been searching all over this website for some simplistic help.
A lot of the examples here are so wrapped in code it's hard to get the understanding
to implement into my own code.
I need to loop through stats on each game and display the information via variables.
Now i can do everything myself, i just can't seem to find a for each loop willing to
display my information
My current code:
$ch2 = curl_init();
// set url
curl_setopt($ch2, CURLOPT_URL, "https://na.api.pvp.net/api/lol/na/v1.3/stats/by-summoner/" . $myid . "/ranked?season=SEASON4&api_key=(REMOVED)");
//return the transfer as a string
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$response2 = curl_exec($ch2);
// close curl resource to free up system resources
curl_close($ch2);
$obj = json_decode($response2, true);
foreach ($obj as $val) {
echo "<b>" . $val['stats']['totalDeathsPerSession'] . "</b><br>";
echo "<b>" . $val['stats']['totalDamageTaken'] . "</b><br>";
echo "<b>" . $val['stats']['totalChampionKills'] . "</b><br>";
echo "<b>" . $val['stats']['totalDeathsPerSession'] . "</b><br>";
}
Here's the JSON data
{
"modifyDate": 1402869729000,
"champions": [
{
"id": 40,
"stats": {
"totalDeathsPerSession": 5,
"totalSessionsPlayed": 1,
"totalDamageTaken": 17488,
"totalQuadraKills": 0,
"totalTripleKills": 0,
"totalMinionKills": 15,
"maxChampionsKilled": 0,
"totalDoubleKills": 0,
"totalPhysicalDamageDealt": 6183,
"totalChampionKills": 0,
"totalAssists": 12,
"mostChampionKillsPerSession": 0,
"totalDamageDealt": 21580,
"totalFirstBlood": 0,
}
},
{
"id": 42,
"stats": {
"totalDeathsPerSession": 6,
"totalSessionsPlayed": 1,
"totalDamageTaken": 10626,
"totalQuadraKills": 0,
"totalTripleKills": 0,
"totalMinionKills": 29,
"maxChampionsKilled": 1,
"totalDoubleKills": 0,
"totalPhysicalDamageDealt": 11166,
"totalChampionKills": 1,
}
],
"summonerId": 29283170
}
it keeps going on and on, i don't want to flood the entire log here.
I am simply just trying to grab some of the data like Total Minion Kills
Total Deaths, Kills.. But it keeps coming up blank with everything i try.
I have attempted so many different ways before coming here. i really hope you can help!
It should be:
foreach ($obj['champions'] as $val) {
I have client and server in php communicating over shared memory, Now I would like to access this shred memory object using Boost.Interprocess how can I access it?
server.php:
function create_image($str){
// Create a blank image and add some text
$im = imagecreatetruecolor(300, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
$stringBanner=exec("date").$str;
imagestring($im, 1, 5, 5, $stringBanner , $text_color);
ob_start();
imagejpeg($im);
$i = ob_get_contents();
ob_get_clean();
imagedestroy($im);
return $i;
}
echo "\n".__FILE__."\n";
$shm_key = ftok(__FILE__, 't');
echo $shm_key."\n";
$shm_id = shmop_open($shm_key, "a", 0, 0);
if ($shm_id) {
//it is already created
shmop_delete($shm_id);
shmop_close($shm_id);
}
//you need to create it with shmop_open using "c" only
echo "try to create\n";
if(!$shm_id = shmop_open($shm_key, "c", 0777, 1024*4))exit(-1);
echo "ID ".$shm_id."\n";
$i=0;
for(;;){
sleep(1);
$s="i=".$i++;
$str=$i;
$im=serialize(create_image($str));
$data=serialize(strlen($im));
$shm_bytes_written = shmop_write($shm_id, $data, 0);
$shm_bytes_written = shmop_write($shm_id, $im, 32);
echo $shm_bytes_written." bytes is written: ".$s." ID = $shm_id\n";
}
client.php
<?php
$shm_key =1946222626;// ftok(__FILE__, 't');
$shm_id = shmop_open(
$shm_key, "a",
0644,1024*4
);
$s=shmop_size($shm_id);
$data = unserialize(
shmop_read( $shm_id, 0,
31)
);
$im = unserialize(
shmop_read( $shm_id, 32,
$data)
);
// Set the content type header - in this case image/jpeg
header('Content-Type: image/jpeg');
// Output the image
echo $im;
What kind of key I should provide to Boost to get this memory region?
boost_client.cpp
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
#include "sys/msg.h"
int main()
{
int msqid;
key_t key;
char f[]="??????";
int mid;
//key = ftok(, 't');
//msqid = msgget(key, 0666 | IPC_CREAT);
std::cout<<msqid<<std::endl;
boost::interprocess::shared_memory_object
shdmem(boost::interprocess::open_or_create,
f,//"shmem_server",
boost::interprocess::read_write);
shdmem.truncate(1024);
std::cout << shdmem.get_name() << std::endl;
boost::interprocess::offset_t size;
if (shdmem.get_size(size))
std::cout << size << std::endl;
}
EDIT:
Well I found the solution in Boost IPC library Docs:
XSI_KEY based example from boost Docs
I'm not an expert in what you're doing, but from what I read in your question and my knowledge, I would drop that pure IPC thing and wrap it into ZMQ (you'll find wrapper in every language you need). It's meant to solve those kind of problems and provide a single API that could run over IPC or more common TCP socket.
So Chrome 14 has implemented hybi10 version of websockets. I have a in house program that our company uses via chrome that uses websockets which is broken with this change.
Has anyone been successful framing the data using a php server? I am able to get the new handshake to work but I can't seem to figure out the framing. There is a python example here https://github.com/kanaka/websockify/blob/master/websocket.py#L233 but I am having a difficult time converting this to php, anyone have a suggestion?
I should mention that the function in question on the python example is decode_hybi().
i just completed a class wich makes the PHP-Websocket-Server of Nico Kaiser (https://github.com/nicokaiser/php-websocket) capable of handling hybi-10 frames and handshake. You can download the new class here: http://lemmingzshadow.net/386/php-websocket-serverclient-nach-draft-hybi-10/ (Connection.php)
This code assumes no errors or malformed frames and is based on this answer - How to (de)construct data frames in WebSockets hybi 08+?.
This code is very basic and is far from a complete solution. It works for my purposes (which are pretty basic). Hopefully it is of use to others.
function handle_data($data){
$bytes = $data;
$data_length = "";
$mask = "";
$coded_data = "" ;
$decoded_data = "";
$data_length = $bytes[1] & 127;
if($data_length === 126){
$mask = substr($bytes, 4, 8);
$coded_data = substr($bytes, 8);
}else if($data_length === 127){
$mask = substr($bytes, 10, 14);
$coded_data = substr($bytes, 14);
}else{
$mask = substr($bytes, 2, 6);
$coded_data = substr($bytes, 6);
}
for($i=0;$i<strlen($coded_data);$i++){
$decoded_data .= $coded_data[$i] ^ $mask[$i%4];
}
$this->log("Server Received->".$decoded_data);
return true;
}
Here is the code to send data back. Again this is pretty basic, it assumes you are sending a single text frame. No continuation frames etc. No error checking either. Hopefully others find it useful.
public function send($data)
{
$frame = Array();
$encoded = "";
$frame[0] = 0x81;
$data_length = strlen($data);
if($data_length <= 125){
$frame[1] = $data_length;
}else{
$frame[1] = 126;
$frame[2] = $data_length >> 8;
$frame[3] = $data_length & 0xFF;
}
for($i=0;$i<sizeof($frame);$i++){
$encoded .= chr($frame[$i]);
}
$encoded .= $data;
write_to_socket($this->socket, $encoded);
return true;
}
I am trying to layer these:
into this:
But what I keep getting is this:
This is the relevant code, Im not sure what Im missing:
$sig_background = imagecreatefrompng("sanctum-signature.png");
imagealphablending($sig_background, false);
imagesavealpha($sig_background, true);
$sig_gamertile = imagecreatefrompng($gamertile_masked_file);
imagealphablending($sig_gamertile, false);
imagesavealpha($sig_gamertile, true);
$sig_gametile = imagecreatefrompng($gametile_masked_file);
imagealphablending($sig_gamertile, false);
imagesavealpha($sig_gamertile, true);
imagecopymerge($sig_background, $sig_gamertile, 175, 2, 0, 0, 64, 64, 100);
imagecopymerge($sig_background, $sig_gametile, 342, 20, 0, 0, 64, 64, 100);
If any more information is missing, please let me know and Ill try to fill in the blanks. Thank you for your time.
edit - here are links to the files (hosted on photobucket)
gamertile
gametile
There's a typo in your code, is it a copy/paste error or a real bug?
You do:
$sig_gamertile = imagecreatefrompng($gamertile_masked_file);
imagealphablending($sig_gamertile, false);
imagesavealpha($sig_gamertile, true);
And then:
$sig_gametile = imagecreatefrompng($gametile_masked_file);
But straight afterwards, you continue to call functions on $sig_gamertile instead of $sig_gametile:
imagealphablending($sig_gamertile, false);
imagesavealpha($sig_gamertile, true);
Obviously radically renaming some vars would help guard against this.
The line:
imagealphablending($im, false);
disables alpha blending. Use true instead of false.