Can socket.io work across domains? - javascript

I have a socket.io implementation, and I'm trying to make it work across domains but it appears it can't. Here's my exact use case:
I have a node.js server running socket.io.
I have a JS / HTML5 game that I want to be able to host from anywhere, which has the client socket.io code and tries to connect to the server.
I have the same JS code running on mobile devices via SpiderMonkey (this is one of the main reasons I need to run this from any domain).
I find that I simply cannot connect to the socket unless I am serving the JS code from my node.js server to a browser. If I simply open the HTML file on my disk from my browser, for example, it will not work.
Server code:
io.on( "connection", function( socket )
{
this.socket = socket;
this.socket.on( "echo", function( str ){ this.socket.emit( "message", str ); }.bind( this ) );
}.bind( this ) );
Client code:
this.socket = io.connect( ip );
this.socket.on("message", function( str ) { console.log( str ); } );
And I can't even connect, I get my print out that it's trying to connect, but it never succeeds and then starts throwing ping errors. So, is this even possible? Or must I do it with long polling or something?
The error:
[Error] Failed to load resource: A server with the specified hostname could not be found. (socket.io, line 0)
EXTRA INFO:
This specifically will not work if I am trying to connect from an HTML file opened from disk using file:///. I am going to try across different machines on the same network...

Yes, Socket.IO works cross-domain just fine. The actual Socket.IO library can/should be loaded from the server hosting it.
EXTRA INFO: This specifically will not work if I am trying to connect from an HTML file opened from disk using file:///.
Don't do that. You run into all sorts of weird issues when loading files off disk vs. over HTTP.
Failed to load resource: A server with the specified hostname could not be found.
This usually implies that whatever hostname you're trying to connect to isn't resolvable, indicating a DNS problem or that you typoed your hostname. In any case, your code example doesn't show the relevant part where the problem may be. Use your browser's developer tools to first determine that everything is loading correctly. Then, verify the address of what you're trying to connect to.

Related

WebSocket connection timed out in EC2 website

I have a problem that seems to me to be impossible to solve, well, I have a website on EC2, I bought my own domain, I added HTTPS using Let's encrypt, and on this website there is a chat, and I am using the PHP Ratchet library to create a connection with websockets, and the problem is that my server doesn't start in the browser, well, I've tried to make my server start with several ports, 3000, 8080, 8181, 8443, 4433, and none of these work, at least when I use the command php chat-server.php to start the PHP server, I don't get any errors, it works, however, when entering the browser, it doesn't display a message in the PHP script console saying that there is a new connection, and the browser console ( chrome) reports a timed out error, that is, it looks like you are not connecting to the server, I really don't know what to do anymore, I don't know if this is because of the HTTPS I'm using, I don't know if should I edit something in the apache configuration, I need the someone help me, please
In fact, I already edited the security group in EC2, I already enabled these ports that I said I tried to use, I restarted the Apache server too and I still get the same error
PHP CODE - chat-server.php :
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Local\Socket\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
4433
);
$server->run();
JS CODE:
var conn = new WebSocket("wss://example.net:4433/chat.php");
ERROR:
failed: Error in connection establishment:
net::ERR_CONNECTION_TIMED_OU

socket.io "net::ERR_FAILED" with cache manifest for Progressive Web App

I'm developing a Progressive Web App which uses a .manifest file to cache all files on the client. I modified the socket.io chat example which is found here:
https://github.com/socketio/chat-example
my modifications can be found here:
https://github.com/TennisVisuals/socket.io.manifest.errors
The first change in the client code is:
external resources (jquery and socket.io client libraries) are accessed locally rather than via remote URLs.
Everything works as expected.
But with the second change:
<html> is replaced with <html manifest="index.manifest">
The application fails, giving this error in the Javascript console:
http://localhost:3000/socket.io/?EIO=3&transport=polling&t=Lij1LRo net::ERR_FAILED
Initial Fix
I've been able to make it work locally by adding the following lines:
enter var connectionOptions = {
"force new connection" : true,
"reconnectionAttempts": "Infinity",
"timeout" : 10000,
};
var socket = io(connectionOptions);
Cloudflare and Nginx
But I'm now seeing stranger behavior when I run with Cloudflare and Nginx.
Without the manifest declaration I get an error, but everything still works!
socket.io-1.7.2.js:7370 WebSocket connection to 'wss://hiveeye.net/socket.io/?EIO=3&transport=websocket&sid=rM2LKvCGJwaFx7RrAAAf' failed: Error during WebSocket handshake: Unexpected response code: 400
after adding the manifest declaration it works exactly once and then fails with the following errors:
socket.io-1.7.2.js:4948 GET https://hiveeye.net/socket.io/?EIO=3&transport=polling&t=Lik5SC5&sid=rM2LKvCGJwaFx7RrAAAf net::ERR_FAILED
GET https://hiveeye.net/socket.io/?EIO=3&transport=polling&t=Lik5STN net::ERR_FAILED
GET https://hiveeye.net/socket.io/?EIO=3&transport=polling&t=Lik5STN net::ERR_FAILED
I suspect that if I can get the initial error to go away when running without the manifest, that may do the trick... but I've been unable to find anything to help me resolve that issue...
Ok, this was really simple once I found out how to ask the right question
Adding:
NETWORK:
*
at the bottom of the manifest file made everything work.
Yes, the "Application Cache" is deprecated:
https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
but I still wanted to make it work!!

Open sessionURL for Autobahn websocket in browser

I have a Pyramid web application on which I would like to embed an iFrame displaying an instance of ParaViewWeb's visualizer so users can display VTU files remotely.
I have successfully done so while running the application on my own workstation by calling a subprocess from Python that executes ParaViewWeb's Quick Start method and returns the URL to JavaScript for iFrame generation.
http://www.paraview.org/ParaView3/Doc/Nightly/www/js-doc/index.html#!/guide/quick_start
However, in order to accommodate multiple users, ParaViewWeb's documentation indicates that
the server must provide a single entry point to establish a connection, as well as a mechanism to start a new visualization session on demand
for which it suggests using Apache as the front-end application and a python launcher to start the process for each session.
Conveniently, I have a "freshly installed Ubuntu Desktop 14.04 LTS" so I used the following guide to configure both the launcher and Apache:
http://www.paraview.org/ParaView3/Doc/Nightly/www/js-doc/index.html#!/guide/ubuntu_14_04
Ok so I'm pretty sure I am missing something major here, but once the launcher is started with /data/pvw/bin/start.sh... how do I then submit the request with information regarding what app to use (visualizer) and what data directory to load???
Update
I am able to launch a session such that a sessionURL with a unique ID is returned by first running
/data/pvw/bin$ ./start.sh
and then entering the following commands in the python interpreter
>>> import requests
>>> import json
>>> data = {"sessionManagerURL": "http://localhost:8080/paraview", "application": "visualizer"}
>>> data = json.dumps(data)
>>> r = requests.post("http://localhost:8080/paraview",data=data)
>>> r.json()['sessionURL']
u'ws://localhost/proxy?sessionId=e2970d68-42c8-11e5-a755-3c970e8061f9'
So now I have a websocket which should contain an instance of ParaViewWeb that I would like to access from the browser... typing the sessionURL as is into the browser does nothing and replacing 'ws' with 'http' opens a page with the following text:
AutobahnPython 0.6.0
I am not Web server, but a WebSocket endpoint. You can talk to me using the WebSocket protocol.
For more information, please visit my homepage.
I am new to both apache and websockets so I am reading up on the protocol on the homepage, but if someone has a quick answer about how to utilize this websocket to display ParaViewWeb to the user I would be very appreciative!!
Note: Command line argument -dr is unknown so omit it from all of the command line arguments given in the guide's launcher.json
Thanks in advance!

API calls are not working in cordova application

I made an application using apache cordova. my server is written in node.js running locally and port 3005. So I want to make API call from cordova I am using backbone in client side.
I written the following code to make API call
makingAPICallForStatus:function(){
var userSessionModel = Backbone.Model.extend({ //Creaating a model for checking user session status
url:"http://localhost:3005/api/user/status/",
});
var userSessionModelObj=new userSessionModel();
this.makeApiCall(userSessionModelObj,"",'GET',function(model,response,options){console.log(response);});
},
makeApiCall:function(modelObj,dataObject,requestType,successCallback){
modelObj.fetch({data:dataObject,
type:requestType,
success:successCallback,
error:function(){console.log("error")}
});
}
If you observe, I mention URL path is :"http://localhost:3005/api/user/status/". This way it's not working. it's showing This request has no response data available
Now I tried with production domain like
URL path is :"http://xxx.xxxx.com/api/user/status/"
This way it's working fine.
Why localhost was not working, I invoke same url directly in my browser working fine. but it's not working in cordova.
Note : I didn't modify anything in www/config.xml file.
What's the problem how can I fix this.
Thanks.
localhost is an alias of 127.0.0.1 even if you are running on an emulator on the same machine, local host is not real. You have to always make calls to an ipaddress or domain name from a device (even virtual devices). This is because on the device localhost is referring to the device not the machine that it may be running from.

PhoneGap app's XMLHttpRequest POST data lost

I'm porting an ajaxed, mobile-optimized website to PhoneGap, but have been unsuccessful in getting any POST to the server. From what I've read, xhreq POSTS are supposed to be possible in PhoneGap.
The specifics: I'm targeting the Android platform using the latest Cordova 3.3.1-0.1.2, the latest Android SDK, and a Galaxy S3 updated by Verizon to Android 4.3. Connectivity is over wifi to my local server. In every attempt, the POST arrives at the server as a GET, with no post data (verified using tcpdump to inspect packets). The mobile-optimized web site works fine in the browser on the same phone, also over wifi.
I've isolated the fail case by creating a brand new Phonegap project, nothing more than:
$ cordova create Hello
$ cd Hello
$ cordova platform add android
Then in index.js, at the end of the onDeviceReady handler, adding a snippet I first tested in a simple browser page (domain substituted here):
// TEST POST CAPABILITY
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState==4 && (req.status==200 || req.status==0)) {
console.log("POST Response: " + req.responseText);
}
};
var t = new Date().getTime(); // Just to foil any caching
req.open("POST", "http://mydomain.com/services/rpc?t=" + t, true); // async
req.setRequestHeader('Content-type','application/text; charset=utf-8');
var postContent = JSON.stringify({id:t, method:"misc.log", params:[{log:"POST Test"}]});
req.send(postContent);
And then run on the phone with:
$ cordova run android
It fails like the fuller app, arriving at the server as a GET with no post data. I verified a couple of configuration item defaults to make sure they were as required:
In config.xml:
<access origin="*" />
In AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
Any ideas as to what might be going wrong, or other things to look in to?
Thanks.
Your content type should be set to
"application/json".
JSON.stringify() creates JSON content.
Next, can you tell us how your server process is determining the request type. Can you post the relevant code?
I would start by adjusting the content type value. See if that makes a difference.
Hope that helps.
The problem was an ip forwarding one, just not the one I'd originally suspected (forwarding to & from port 80 to my local server on port 8080, which I've used for years as a convenience to allow not having to add :8080 into the browser url all the time).
It was this:
In the MX records for "mydomain.com", I had www.mydomain.com pointing to my server's IP address, but the root mydomain.com (the host address I was using in the url to XMLHttpRequest), redirecting to www.mydomain.com.
This worked in a normal browser session, as if you type in mydomain.com, it just goes to www.mydomain.com, then runs from there - and it would use all relative paths in the xhreq's.
In PhoneGap, however, which requires the full path be specified, the POSTs were not making it through the redirect. It was also causing sluggish image loading behavior and some bizarre communication hangups after many loads - I just hadn't realized the problem had the same root cause (rather I was getting worried about WebView performance).
The great news is that POST is working fine now, and the WebView appears to be plenty speedy for my needs.
To summarize the solution: make sure that the subdomain (or lack thereof) in fully qualified urls passed to XMLHttpRequest (as required in PhoneGap) are mapped to an ip address (A record), and not redirected, in the MX records for your domain.

Categories

Resources