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.
Related
I've been trying to do this but can you connect to another websites their socket.io server? I've been trying to scrape data from a website that uses socket.io for live updates. It would be very handy if this were to be possible.
I'm trying to get live updates from the website https://www.ethercrash.io/ - However I tried the following code and wouldn't get any updates other than a connection;
var io = require('socket.io-client');
var socket = io('https://www.ethercrash.io')
socket.on('connect', function(){
console.log(true);
});
socket.on('msg', function(data) {
console.log('chat message');
});
socket.on('disconnect', function(){
console.log(false);
});
Am I doing something wrong or is this just not possible?
I use the following in all my node.js / express / socket.io projects. Hopefully it helps you out.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
$(document).ready(function() {
// NOTE, I AM FORCING WEBSOCKET TRANSPORT HERE. AND AM NOT ALLOWING
// SOCKET.IO TO FALL BACK TO LONG POLLING FALLBACK,
// SO YOU CAN REMOVE THE TRANSPORTS AND GO WITH SOCKET.IO DEFAULTS
// PORT I'M USING IS 3000 -- SO THE PORT CAN BE IMPORTANT, DEPENDING ON YOUR USASGE
var socket = io.connect("https://MY-SERVER-NAME-HERE.eastus.cloudapp.azure.com:3000", {
secure: true,
transports: ["websocket"],
path: "/socket/socket.io"
});
// EVERY TIME THE NODE.JS SERVER SENDS US 'MESSAGE' WE'LL DISPLAY THAT UPDATED NUMBER IN A DIV
socket.on("message", function(msg) {
document.getElementById("message").innerHTML = msg;
});
});
</script>
</head>
<body style="width: 100%;">
<div id="message" style="text-align: center; width: 100%; font-size: 2em;"></div>
</body>
</html>
You also are depending on that 'other site' (running the socket server) emitting out to either ALL connected clients or to your connection specifically. Unless either of those happen, you will only have a connection with no messages being emitted out (to be read / parsed).
Sockets are really fun to work with and full of potential once you get the hang of it!
I'm trying to use an html page in order to test the connection with my server.
I've got no problem with my server.js
var http = require('http');
var url = require("url");
// Chargement de socket.io
var io = require('socket.io').listen(server);
var server = http.createServer(function(req, res) {
var page = url.parse(req.url).pathname;
// Quand un client se connecte, on le note dans la console
});
io.sockets.on('connection', function (socket) {
console.log('Un client est connecté !');
});
server.listen(8080);
My client should is an html page here
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Communication test with socket.io !</h1>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://localhost:8000/server_node/node_modules/socket.io/lib/socket.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
</script>
</body>
</html>
Problem is, when I load the html client, I've got this error
socket.js:6 Uncaught ReferenceError: require is not defined
at socket.js:6
I'm not trying to implement a real client, I just want a simple page in order to do some connection test.
Thanks for your help
EDIT: Problem fixed, it was all because I wasn't loading the html file from the serverlike this fs.readFile('./ClientTest.html', 'utf-8', function(error, content) {
As this is just used to do some test, it's fine if it works this way; the client side will be with an other platform.
Sorry for that useless issue :(
You appear to be importing the server-side library on the client, you want to be importing the client-side one.
As per the docs, this is automatically served when socket.io runs on the server which you can import via
<script src="/socket.io/socket.io.js" />
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 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
I'm having trouble getting the now.js chat client tutorial to work. (I've also followed this video almost exactly).
server.coffee:
fs = require 'fs'
http = require 'http'
now = require 'now'
server = http.createServer (req, res) ->
fs.readFile(
'index.html'
(err, data) ->
res.writeHead(
200
'Content-Type': 'text/html'
)
res.end(data)
)
server.listen 8080
everyone = now.initialize(server)
everyone.now.distributeMessage = (msg) ->
everyone.now.receiveMessage(#.now.name, msg)
index.html:
<html>
<head>
<title>nowjs title</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/Flotype/now/master/lib/now.js"></script>
<script type="text/javascript">
$(document).ready(function() {
now.name = prompt("What's your name?", "");
now.receiveMessage = function(name, msg) {
return $("<div></div>").text("" + name + ": " + msg).appendTo("#msg");
};
return $("#send-button").click(function() {
now.distributeMessage($("#text-input").val());
return $("#text-input").val("");
});
});
</script>
</head>
<body>
<div id="msg"></div>
<input type="text" id="text-input">
<input type="button" value="Send" id="send-button">
</body>
</html>
When I load up the server with node server.js,
I get an error that says "require not defined" on line 1 of now.js. Consequently, the client side code can't find the variable 'now'.
I understand that 'require' is a node function, but how do I get the client to understand that?
Any help will be appreciated.
The file you're including in your client source (../Flotype/now/master/lib/now.js) is the Node server side code that is included in your node process when calling now = require 'now'.
So changing your included client source file from .../Flotype/now/master/lib/now.js to /nowjs/now.js will fix your problem.
Where does this /nowjs/now.js file come from?
When using NowJS (and many other npm packages that do client/server communication) you extend the server object. This is done with the line everyone = now.initialize(server) (Code Here).
What the initialize function does is wrap your server with the fileServer (Code Here) class in NowJS. This adds a resource under the "folder" nowjs which serves the client now.js file.
I got this error when trying to run nodejs file with js command instead of node.
Eg: if the nodejs file name is test.js, I was doing
js test.js
instead of
node test.js
I hope this helps too for people searching for this error.