I have a bit of an issue. I'm trying to create a dynamic web app using node.js/express.js/now.js. I've done everything as shown in the small sample code at http://nowjs.com/download , with no success, the client-side now.js script hosted properly, but now.ready(..) never fires. The only differences are that I use express and my server which is used to initialze now.js is https.
Do you have any ideas which could cause it not to work?
server side:
var server = express.createServer(..);
..
server.listen(port, function() {..});
var nowjs = require('now');
var everyone = nowjs.initialize(server);
everyone.now.log = function(msg) { console.log(msg); }
client side:
<script type="text/javascript" src="/nowjs/now.js"></script>
<script type="text/javascript">
now.ready(function() { now.log('asd'); alert('asd'); });
</script>
Any help would be highly appreciated!
Best, Kornel
Well, found the answer.
Long answer: now.js has an issue when determining the communication port on which socket.io should communicate. This issue seems only to appear when using default https port (443).
I've found two solutions, the ugly one:
https://groups.google.com/forum/?fromgroups=#!topic/nowjs/8cO9D77tN2o
Basically you need to edit the source code of now.js at now/lib/fileServer.js and replace
var hostPort = options['port'] || host[1] || '80';
with
var hostPort = options['port'] || host[1] || ((request.headers.referer.split(':')[0] === 'https') ? '443' : '80');
The nicer one is to set port options to socket.io. Lucky us, this is supported by now.js:
var everyone = nowjs.initialize(server, {port: port, socketio: {transports: ['xhr-polling', 'jsonp-polling']}});
I hope that this will help others having the same issue and also hope that this behavior will be fixed later in now.js.
Best regards: Kornel
Running latest version of node and now on OSX, with Safari.
server.js
var html = require('fs').readFileSync(__dirname+'/index.html');
var httpServer = require('http').createServer(function(req, response) {
/* Serve your static files */
response.end(html);
})
httpServer.listen(8080);
var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);
console.log('done');
everyone.now.logStuff = function(msg){
console.log(msg);
}
index.html
<script type="text/javascript" src="http://localhost:8080/nowjs/now.js"></script>
<script type="text/javascript">
now.ready(function(){
// "Hello World!" will print on server
now.logStuff("Hello World!");
});
</script>
done..
Start the server:
node server.js
Open your browser:
http://localhost:8080
Related
I have a node.js socket server using socket.io.
I'm building a firefox addon, where I load a pageworker. The html in the following page is as follows:
<html>
<head>
<script type="text/javascript">
//THIS DOESN'T WORK
var exampleSocket = new WebSocket("ws://someip:port");
exampleSocket.onopen = function (event) {
console.log("socket opened!");
};
//THIS WORKS
var exampleSocketa = new WebSocket("ws://echo.websocket.org");
exampleSocketa.onopen = function (event) {
console.log("socket to echo opened!");
};
</script>
</head>
<body>
</body>
</html>
I can open a websocket to echo.websocket.org, but not my own server. I get a "debug: destroying non-socket.io upgrade" message. I can switch it off with the option: { 'destroy upgrade': false }, but then I see no debug output from server, and no connection is made.
What am I doing wrong? How can I get a socket open to my socket.io server?
So after some more googling, it turns out that I need to require socket.io on the client side. Even though socket.io uses websockets, it prefers talking to itself.
I've wrote a simple node.js app by socket.io some weeks ago. My program is fine on my PC but when i tried to run it on my laptop. I faced a really weird error on my console.
note that I'm running node on 127.0.0.1:2324. I don't know what is that ip (0.0.9.20) on the chrome console.
Again, my code is correct cause it's working fine on my PC.
And I get this on my cmd:
my paint.html code is something like this:
<script src="http://127.0.0.1/node/paint/js/jquery.js"></script>
<script src="http://127.0.0.1/node/paint/js/cursor.js"></script>
<script src="http://127.0.0.1/node/paint/js/controllers.js"></script>
<script src="http://127.0.0.1/node/paint/js/core.js"></script>
<script src="http://127.0.0.1:2324/socket.io/socket.io.js"></script>
<link href="http://127.0.0.1/node/paint/css/style.css" rel="stylesheet" />
core.js:
// broadcat function
function broadcast(data)
{
var socketio = io.connect(serverPort);
socketio.emit("message_to_server", { pen : data});
}
// receive data from server
var socketio = io.connect(serverPort);
socketio.on("message_to_client", function(data)
{
var res_brush = data['pen'];
var brush_data_rec = res_brush['pen'].split('|');
draw(brush_data_rec[0],
brush_data_rec[1],
brush_data_rec[2],
brush_data_rec[3],
brush_data_rec[4],
brush_data_rec[5],
brush_data_rec[6]);
});
update:
You should explicitly specify the target hostname on the client to connect to to avoid confusing the client on which address to connect to. There's also a cleaner way to specify a target port.
var socket = io.connect('http://localhost/', {
'port': 8080,
'transports': ['websockets']
});
I've created a basic node.js server program and used socket.io to pass some field data from a client (see below). Pretty chuffed as I'm new to this business. I liked this node-express-socket.io approach as its all Javascript and is apparently usable by most browsers (incl' mobile). The problem is I've kind of fumbled my way through and do not not fully understand what I have created! Two questions...
1) Do I need to use the "//ajax.googleapis.com...jquery..."? This is annoying as the browser will need to have an internet connection to work. Is there another way to access the html doc elements without needing an internet connection?
2) What does the "app.use(express.static...." line do? The "app.get..." function seems to require this to work.
If there are any other general comments about my code please let me have it!
Cheers,
Kirbs
Client side code:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect(document.location.protocol+'//'+document.location.host);
function clicked(){
$(function(){
var makeInput=$('.app').find('#make').val();
var modelInput=$('.app').find('#model').val();
socket.emit('make', makeInput);
socket.emit('model', modelInput);
});
};
</script>
Server side code:
var express = require('express');
var http = require('http');
var socketio = require('socket.io');
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
app.use(express.static(__dirname));
app.get('/', function (req, res) {
res.render(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.on('make', function (make) {
socket.on('model',function (model){
console.log('recieved message:', make+','+model);
});
});
});
server.listen(8000);
1) As you have setup a static web server (see answer 2), you could simply download the jquery source and serve the .js file from there.
2) "app.use(express.static...." configure a static webserver and setting up the http root directory to the directory that your node.js script lives, as indicated by the __dirname variable. For more detail, see app.use API reference.
As result, I would recommend you change you app.use to:
app.use(express.static(__dirname + '/public'));
and place all your static files, including your jquery file(s), under a public subdirectory.
Also, your server side code has a dependency on sequence of make and model which should be changed. For example, if you switch the emit order to model then make, you should see that your server's console.log will be picking up the make from the previous call.
Instead, try something like:
// On server:
socket.on('info', function (info) {
console.log('recieved message:', info.make+','+info.model);
});
// On client:
socket.emit('info', { make: makeInput, model: modelInput })
1) You can serve the jQuery library also from your server if you like that better. You should put it in the public/vendor or public/js folder in your project.
2) This is a middleware call from Express framework, which uses in turn the Connect middleware stack. Read up on this here.
I just deployed a node.js site to AppFog. It works fine locally when I go to "http://localhost:8080", but when I got to the one on AppFog: http://bandwithfriends.aws.af.cm/ I get the following Chrome console error:
XMLHttpRequest cannot load http://localhost:8080/socket.io/1/?t=1357769454152. Origin http://bandwithfriends.aws.af.cm is not allowed by Access-Control-Allow-Origin.
SERVER CODE:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
static = require('node-static'); // for serving files
// This will make all the files in the current folder
// accessible from the web
var fileServer = new static.Server('./');
app.listen(process.env.VCAP_APP_PORT || 8080);
io.configure('development', function(){
io.set('transports', ['xhr-polling']);
});
CLIENT CODE index.html:
I am including socket.io like this:
<script src="/socket.io/socket.io.js"></script>
CLIENT CODE script.js:
var url = 'http://localhost:8080';
var socket = io.connect(url);
How do I fix this?
All I had to do to fix this was remove the url on the client side code:
var socket = io.connect();
Hope this helps anyone else having the same problem!
Both your client side and server side are wrong.
On the client side; make this change:
var url = io.connect('http://<your domain name>');
//For example: var url = io.connect('http://shash7.ap01.aws.af.cm');
On the server side, you need to implement socket.io like this:
var app = require('express')() , server =
require('http').createServer(app) , io =
require('socket.io').listen(server);
server.listen(80);
The above code was taken from the socket.io site. They changed the way socket.io listens in the 0.9 version so use the above version.
Other than that, everything looks fine. Tell me if you still can't figure this out.
I started reading about node.js a few weeks back and decided to learn more about it. I installed node and socket.io and a few other packages (express and some I don't remember) on my Linux server (Turnkey Linux, basically Ubuntu). I found some tutorials and went through them, and couln't get any of the clients to send messages back to the server. Here are some of the tutorials I went through (I have more, but the site wouldn't let me post more links):
Simple chat room
http://vivahate.com/2011/03/25/a-simple-chat-room-in-node-js/
Simple Socket.io real-time chat
http://webdevrefinery.com/forums/topic/7991-simple-socketio-real-time-chat/
Note that the webdevrefinery one has a live demo on the web, which works in my browser from 2 different computers. There is a link to code which I downloaded and ran, and the server runs just fine. I go to the url (192.168.0.30:3000 on my LAN) and it shows the correct HTML and the console outputs "debug - served static /socket.io.js" as soon as I browse to the URL. When I enter info and it "enter" nothing happens. I put alerts into the code and it seems to fail on the "socket.send" line in "sendMsg()". Here is the code I'm using:
server.js:
var http = require('http'),
sys = require('sys'),
fs = require('fs'),
io = require('socket.io');
var server = http.createServer(function(req, res) {
fs.readFile('chat.html', 'binary', function(err, data) {
if( err ) {
res.writeHead(500, {'Content-type': 'text/html'});
res.write(data + "\n");
res.end();
return;
}
res.writeHead(200, {'Content-type': 'text/html'});
res.write(data, 'binary');
res.end();
});
});
server.listen(3000);
var socket = io.listen(server);
socket.on('connection', function( client ) {
client.on('message', function(data) {
console.log("Message: " + JSON.stringify(data));
socket.broadcast(data);
});
client.on('disconnect', function() {
});
});
client.html
<html>
<head>
<style type="text/css">
#msgs {
height: 50%;
overflow-y: scroll;
}
div.odd {
background-color: gray;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="http://192.168.0.30:3000/socket.io/socket.io.js"></script>
<title>Realtime Chat Test</title>
</head>
<body>
<div id="container">
<div id="msgs"></div>
<div id="form">
<form id="chat" action="javascript:sendMsg()">
Username:<input type="text" name="username" /><br />
Message:<input id="msg" type="text" name="message" /><br />
<input type="submit" />
</form>
</div>
</div>
</body>
<script type="text/javascript">
var socket = new io.Socket("192.168.0.30", {port:3000});
socket.connect();
var classes = new Array('even', 'odd');
var numMsgs = 0;
function reconnect() {
if( socket.connecting ) {
setTimeout('reconnect()',1000);
}
else if( !socket.connected ) {
socket.connect();
setTimeout('reconnect()',1000);
}
}
socket.on('disconnect', function() {
reconnect();
});
socket.on('message', function(data) {
var ms = JSON.parse(data);
if( ms.username !== undefined && ms.message !== undefined ) {
numMsgs++;
$('#msgs').append( function() {
var d = $('<div class="'+classes[numMsgs%2]+'"/>');
d.text(ms.username + ' says: ' + ms.message);
return d;
});
var objDiv = document.getElementById('msgs');
objDiv.scrollTop = objDiv.scrollHeight;
}
});
function sendMsg() {
var values = {};
$.each($('#chat').serializeArray(), function(i,v) {
values[v.name] = v.value;
});
document.getElementById("msg").value = "";
socket.send(JSON.stringify(values));
}
</script>
</html>
The distribution of Linux I'm using doesn't have X or anything like that as I do all my browsing from Windows machines, which is why I'm not testing from localhost, although I'm assuming this should work from other hosts as evidenced by the HTML being served and the message being output when I surf to the page. Any ideas on why I never get any messages from the client to the server? I'm assuming I'm making the same mistake with every tutorial as there are about 8 others I've tried but I always have the same issue. Thanks.
Darryl
This is in response to the comments after Alfred's answer. I couldn't figure out how to put another comment in that line so I'm posting an "answer".
#Alfred - thanks for the example, but that does seem like a lot to go though as Daniel said considering I haven't gotten a simple message to go through. #Daniel - As far as the documentation goes I still don't get the idea of how to actually use the example on the socket.io homepage. There's a "How to use" link that does nothing and a Wiki link that doesn't explain anything about the examples. I know how to start the server, but still don't know how to connect the client to the server or even how to "start" the client. Most of the tutorials have some sort of "link code" that points to the client page from the server, then you just point the browser at "http://yoursiteaddress:port" and the page is shown. The code on the socket.io homepage has no "connection" like this between the client and server code. Are you supposed to surf to the "client" code? I tried that and it serves the exact same code no matter what URL I go to assuming I'm going to "http://yoursiteaddress:port" which makes sense, but I haven't seen any documentation actually explaining how to use that code. Hence my going to tutorials which apparently all use old code. Is there some documentation that I'm missing?
I bet you the problem lies in your dependencies. Let's look at my dependencies for example:
$ npm ls
├─┬ express#2.4.3
│ ├─┬ connect#1.6.0
│ │ └── qs#0.3.0
│ ├── mime#1.2.2
│ └── qs#0.3.0
├─┬ socket.io#0.7.7
│ ├── bison#1.1.1 extraneous
│ ├── policyfile#0.0.3
│ ├── redis#0.6.0
│ └─┬ socket.io-client#0.7.4
│ └── uglify-js#1.0.3
From socket.io 0.6.x to 0.7.x the API underwent some major changes. It looks like you are reading old tutorials using socket.io 0.6.x and you have installed 0.7.x. I advice you to read migration instructions.
I like to provide you real simple demo(utilizes express which you have installed) which hopefully does work.
var app = require('express').createServer(),
sio = require('socket.io');
app.get('/', function(req, res){
res.send('<script src="/socket.io/socket.io.js"></script>\
<script>\
var socket = io.connect("http://192.168.0.30");\
socket.on("news", function (data) {\
alert(data.hello);\
});\
</script>');
});
app.listen(3000);
var io = sio.listen(app);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
});
Should alert world when you connect to socket.io server.
What I also think will work with your example is installing socket.io 0.6.18 which is the latest 0.6.x right now inside your directory inside the folder node_modules. Node.js will include that module locally thanks to node.js module system. You can do this by creating that directory if that not already exists issuing mkdir -p node_modules. Next install socket.io issuing npm install socket.io#0.6.18. Then I think you should be able to run those old examples.