I’m having a problem getting started with Node.js.
I’ve created a basic server that I know works, because if I navigate to http://localhost:5000 in my browser I get the expected message. However, I’m having trouble then connecting to this server on the client side with a basic HTML page.
My Node.js app looks like this:
var http = require('http');
var socket = require('socket.io');
var port = process.env.PORT || 5000;
var players;
var app = http.createServer(function(request, response) {
response.write('Server listening to port: ' + port);
response.end();
}).listen(port);
var io = socket.listen(app);
function init() {
io.configure(function() {
io.set('transports', [ 'xhr-polling' ]);
io.set('polling duration', 10);
});
io.sockets.on('connection', onSocketConnection);
};
function onSocketConnection(client) {
console.log('New connection');
console.log(client);
};
init();
My HTML page looks like this (based on https://github.com/mongolab/tractorpush-server/blob/master/index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.on('all', function(data) {
console.log(data);
});
socket.on('complex', function(data) {
console.log(data);
});
</script>
</body>
</html>
I understand that the sockets.io.js file is automatically generated by socket.io, but I just get the following error when I view my index.html file:
Uncaught ReferenceError: io is not defined
How do I actually connect to my server?
Related
There are other posts asking the same question but my situation is different. The code works but with the error "failed: Connection closed before receiving a handshake response" displayed in Chrome console. I tried to strip all the code and came up with a very slimmed down code which continues to give the error. Here is the test case:
Server side:
var http = require('http');
var express = require('express');
app = express();
server = http.createServer(app);
serveFile = function (req,res) {
res.sendFile(__dirname + '/socket.html');
};
io = require('socket.io')(server);
io.sockets.on('connection',function(socket) {
socket.on('from_client',function(data) { console.log(data.name); });
socket.emit('dateFromServer', {'date': new Date()});
});
app.use(serveFile);
io.listen(server);
server.listen(2000);
Client side: (the socket.html file)
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.7.js"></script>
</head>
<body>
<script>
var socket = io.connect();
socket.on('dateFromServer', function(data){
$('#date').text(data.date);
});
socket.emit('from_client',{'name':'John'});
</script>
<div id="date">Date will be displayed here</div>
</body>
</html>
~
Please, can someone explain what is causing the error? The messages are sent/received, from the client/server, as expected.
~
I use the following module and it works fine for reverse proxy
https://github.com/nodejitsu/node-http-proxy
currently I've used the code like the following example
httpProxy.createServer({
target: 'ws://localhost:9014',
ws: true
}).listen(8014);
my question is how can I check/simulate that the websockets are working?
Any test will be helpful...
In response to the OP's request for browser test, I modified my original solution to proxy both HTTP and WS traffic to a server where an index.html file is served. This file then connects the browser to the proxy server via WebSocket, which the proxy then proxies to the main server. A simple message is printed on the browser document from the main server.
So that there is no need to copy/paste anything, I created this repo with full instruction: https://github.com/caasjj/httpproxy.git
Here is the code in case others want to look at it here. To run the whole thing, create the two server files and the index.html file, start the servers with node proxyreceiver.js and node proxyserver.js and then navigate to localhost:8014/index.html.
(proxyserver.js):
var httpProxy = require('http-proxy');
var http = require('http');
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9014
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
proxyServer.listen(8014);
(proxyreceiver.js):
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(9014);
function handler (req, res) {
res.writeHead(200);
fs.readFile('index.html', function(err, data){
res.end(data);
})
}
io.on('connection', function (socket) {
socket.emit('data', { message: 'Hello World!' });
socket.on('resp', function(msg) {
console.log('Got message: ', msg);
});
});
(index.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web Socket Proxy Test</title>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script>
var socket = io('http://localhost:8014');
var p = document.createElement("p")
socket.on('data', function (data) {
console.log('Got', data);
p.innerHTML = "Received:" + data.message;
document.body.appendChild(p);
});
</script>
</head>
<body>
<h1>Test ProxyServer</h1>
</body>
</html>
The best way to test is to create a client to connect to it.
there are many ws modules around. Or you can use this: https://www.websocket.org/echo.html just put your url there and test it.
I uploaded a server-side code to AWS Amazon EC2 with node.js and socket.io.
When I connect to that server from browser(both on desktop and ios safari), it works with no problem.
But, when I create a cordova project and modify some of the codes to comply with cordova, get it run on ios device, it doesn't work!
I tried
<access origin="My-server-side-url-comes-here*"/>
but it didn't solve the problem.
Also, i opened up port :9000 on EC2 for TCP connection.
It seems that socket = io.connect(serverUrl); is causing problem..
I've been struggling to get this work for days now...
Can anyone tell me how to get socket.io work with external host, phonegap, and ios?
server side code uploaded to AWS Amazon EC2 (app.js)
var http = require('http');
var socketio = require('socket.io');
var server = http.createServer(function (request, response){
console.log('server created');
}).listen(9000, function(){
console.log('server running!');
});
var io = socketio.listen(server);
io.sockets.on('connection', function(socket){
socket.on('msg', function(data){
console.log(data);
io.sockets.emit('msg_by_server', "server got your msg:"+data);
});
});
client-side code that works with desktop browsers and iPhone safari(which works fine) (index.html)
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.0.0.js"></script>
<script>
var socket;
var serverUrl = "sampleURL.compute.amazonaws.com:9000";
window.onload = function(){
socket = io.connect(serverUrl);
socket.on('msg_by_server', function(data){
alert(data);
});
}
var sendMessage = function(){
socket.emit('msg', 'msg from client');
}
</script>
</head>
<body>
<button onclick = 'sendMessage();'>Message Send</button>
</body>
</html>
different client-side code used for phonegap(which doesn't work) (index.html)
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="http://cdn.socket.io/socket.io-1.0.3.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
alert('check1');
var socket="";
app.initialize();
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
alert('check2'); // shows up
var serverUrl = "sameURL.compute.amazonaws.com:9000";
socket =io.connect(serverUrl);
alert('check3'); // doesn't show up
socket.on('connect', function(){
socket.on('msg_by_server', function(data){
alert(data);
});
socket.emit('msg', 'msg from client')
});
}
var sendMessage = function(){
alert(socket);
socket.emit('msg', 'msg from client');
};
</script>
</head>
<body onload="onDeviceReady();">
<!--
i put onload="onDeviceReady();" because
document.addEventListener("deviceready", onDeviceReady, false);
doesn't seem to work for some reason..
-->
<button onclick = 'sendMessage();'>amessageSend</button>
</body>
</html>
I have an instant messaging chat application in the making, and am having problems getting my client to receive data from my server. Could anyone explain to me why this is happening?
app.js
var http = require("http");
var express = require("express");
var socket = require("socket.io");
var app = express();
app.use(express.static(__dirname + "/public"));
var server = http.createServer(app);
server.listen(8080);
var io = socket.listen(server);
io.sockets.on("connection", function(client) {
client.on("join", function(name) {
client.set("nickname", name);
console.log(name + " connected."); // logs name correctly
client.broadcast.emit("names", name);
});
});
index.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var server = io.connect("http://localhost:8080");
server.on("connect", function(data) {
nickname = "";
while (nickname == null || nickname.trim() == "") {
nickname = prompt("Enter name");
}
server.emit("join", nickname);
});
server.on("names", function(data) {
document.getElementById("txtNames").value = data;
});
</script>
</head>
<body>
<textarea id="txtNames"></textarea>
</body>
</html>
Do you know what a broadcast is? When you broadcast a message as a result of an event from a socket, The message is emitted to all connected clients except for the socket who triggered the event. Same is your case. If you want to emit names event to your connected client then use
socket.emit("names", name); in your app.js
I'm starting playing with node.js and as everybody, I want do a chat.
My idea is run node.js with socket.io in the port 9090, for example, and my client html in the port 8080. My html client will be served independent.
My server:
var sys = require('sys');
var express = require('express');
var io = require('socket.io');
var app = express.createServer();
app.listen(8080);
var socket = io.listen(app);
socket.on('connection', function (client) {
client.on('message', function (msg) {
socket.broadcast(msg);
});
client.on('disconnect', function () {
});
});
My client:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script>
$(document).ready(function () {
var socket = new io.Socket("localhost", {port: 8080});
socket.on('connect', function () {
socket.send('A client connected.');
});
socket.on('message', function (message) {
$('div#messages').append($('<p>'), message);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
socket.connect();
$('input').keydown(function (event) {
if(event.keyCode === 13) {
socket.send($('input').val());
$('input').val('');
}
});
});
</script>
</head>
<body>
<input type="text" style="width: 300px;" />
<div id="messages" style="border:solid 1px #000;"> </div>
</body>
</html>
I'm running in ubuntu 11.04 with node.js v0.4.10.
The server works fine, but the client can't do connection, in the console.log on google Chrome I received this message:
XMLHttpRequest cannot load http://localhost:8080/socket.io/xhr-polling//1311465961485. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
The server.js is in a folder in /var/www/cliente/chat/public.
What's the problem?
Your client code is not actually being served from port 8080 as you want.
var sys = require('sys');
var express = require('express');
var io = require('socket.io');
var app = express.createServer();
app.listen(8080);
app.use(express.static(__dirname));
app.get('/', function(req, res){
res.render('index.html', { title: 'Chat' });
});
var socket = io.listen(app);
socket.on('connection', function (client) {
client.on('message', function (msg) {
socket.broadcast(msg);
});
client.on('disconnect', function () {
});
});
This should fix your Access-Control-Allow-Origin errors. Execute node server.js and connect to http://localhost:8080. A couple additional notes:
Make sure you have installed socket.io 0.6.x since that's what you are including in your html file. 0.7.x is backwards incompatible.
With this configuration you'll be running socket.io on the same port you are serving your page from (as opposed to 9090).
When I updated my client to:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect("http://localhost", {port: 8080});
socket.on('connect', function () {
socket.send('A client connected.');
});
socket.on('message', function (msg) {
$('div#messages').append($('<p>'), msg);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
$(document).ready(function(){
$('#btn_send').click(function (event) {
socket.send($('#txt_msg').val());
$('#txt_msg').val('');
});
});
</script>
</head>
<body>
<input type="text" id="txt_msg" style="width: 300px;" /><input type="button" id="btn_send" value="send" />
<div id="messages" style="border:solid 1px #000;"> </div>
</body>
</html>
Everything worked.
I was using a version 0.7 of the socket.io that was the problem: https://github.com/LearnBoost/Socket.IO/wiki/Migrating-0.6-to-0.7
You cannot make AJAX requests to URLs that are not on the same hostname and port as the current page. It's a security restriction in all web browsers.