In my routes.js file I have a route to /test as follows:
app.get('/test', function(req, res, next) {
res.sendFile(__dirname + '/test.html');
var nsp = io.of('/test');
console.log(nsp);
nsp.on('connection', function(socket){
console.log('connection made');
socket.on('new_task', function(msg){
nsp.emit('new_task', msg);
});
});
});
In test.html I have attempted a connection to the /test namespace
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('/test');
$('.exp_addtask').click(function(){
socket.emit('new_task', $('#m').val());
$('#m').val('');
});
socket.on('new_task', function(msg){
$('#messages').append('<div class="task-item"><div class="toggle"></div><p>' + msg + '</p></div>');
});
</script>
There are no errors on runtime and I see all details of the nsp connection when I access http://localhost/test, but what I can't see is that a connection has been made when the page is accessed. Can't see any of the sockets triggering either as they would in the global namespace.
EDIT: At the end of index.js here is how I bring in routes and start the server:
require('./routes')(app);
http.listen(80, function(){
console.log('listening on *:80');
});
Any help is much appreciated.
Finally got it working, don't need to put anything in the routes section (didn't work either if I put it outside the /test route handler)
This successfully works now when I access /test:
var test = io.of('/test');
test.on('connection', function (socket) {
console.log('connection to test');
});
Related
I'm trying to come to terms with how WebSockets work in Node.js but I'm having some trouble with sending a message.
I have my WebSocket server configured as follows (index.js)
var ws = require("ws");
var wsserver = new ws.Server ({
server: httpserver,
port: 3030
});
wsserver.on (
"connection", function connection(connection) {
console.log("connection");
}
);
wsserver.on (
"open", function open(open) {
console.log("open");
}
);
wsserver.on (
"message", function message(message) {
console.log("message");
}
);
This seems to be working ok because I can establish the connection using
var wscon = new WebSocket("ws://192.168.20.88:3030");
Which then gives me the connection output on the server. If I try to use send though nothing seems to happen and no error messages
wscon.onopen = function(open) {
wscon.send("test message");
}
I must be missing something but I don't know what
I might have an answer for this but I'm not entirely sure just yet, I'm going to put this here just in case.
I think the problem is that the message listener is added to the wrong object (the server object), I tried to add the message listener to the connection object passed to the server and it seems to be working but I'm not 100% sure why
wsserver.on (
"connection", function connection(connection) {
console.log("connection");
connection.on (
"message", function message(message) {
console.log("message : " + message);
}
);
}
);
Which dependency works for me?
I have been using socketIO for a while now and it works perfectly for Node.JS API's / servers. There are millions of tutorials online for this framework and I'll tell you one them.
How to install?
If you use NPM as your package manager in Node.JS just down it with the following command:
npm install --save socket.io
In case you're using yarn you can install socketIO as following:
yarn add socket.io
Setup the socket server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// Used for serving the HTML page (if used)
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
// Listen for new connections
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Now in index.html I add the following snippet before the :
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
In your front-end you are able to fire of an event via the socket by calling the following function / code:
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
});
</script>
In our case we emitted an event called chat message. So in order to receive the value send over the socket connection we call the following code in our backend / api:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
and that is basically how you use socket with the library SocketIO. Hope this helped fixing your issue!
So I'm using a singleton pattern to set up my websocket.
var sio = require('socket.io')
var io = null;
exports.io = function () {
var socket;
if(io === null){ // Initialise if not already made
io = initialize(server);
}
return io;
};
exports.initialize = function(server) {
io = sio.listen(server);
var connections = [];
console.log('IO Initialized!\n')
io.on('connection', function(socket){
connections.push(socket);
console.log('Connected: %s sockets connected', connections.length);
socket.on('disconnect', function(data){
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected: %s sockets connected', connections.length);
});
// Update function used to send messages to and from backend
socket.on('update', function(data){
io.sockets.emit('new message', {msg: data});
});
});
};
And then in my public/javascript files I can call these like so
$(function(){
var socket = io.connect();
socket.emit('update', 'Test Update');
socket.on('update', function(data){
console.log('here: ' + data);
});
});
and in my route file I have
router.use(function(req, res, next){
if(socket === undefined){
socket = io.io();
}
next();
});
router.get('/', function(req, res, next){
socket.on('update', function(data){
console.log('in routes');
});
socket.emit('update', 'leaving routes');
});
I can emit successfully from the routes file to the public js file (from back end to front end). However, I can't send information from the public js file to the routes file, it only sends to the singleton pattern js file. How can I get it to send to the routes file instead? If I'm going about this the wrong way could somebody please provide an exapmle of how to communicate between a route and a public js file?
As far as I can tell, there's nothing wrong with your singleton setup.
However, every place where you're going to be listening for events, you have to wrap it in io.on('connection', ...). Making it a singleton doesn't prevent this from being a requirement.
Edit: I may be wrong here, I've just noticed that exports.initialize isn't actually returning connections. Tried that?
I have deployed below code in OpenShift Cloud platform by Red-hat for NodeJs chat application, I am not getting any error in Console(F12) and response code as Ok 200..but the application is not working
Server(you can find complete source at https://github.com/varund29/openshift/blob/master/index.js)
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server, { origins:'http://nodejs-atnodejs.rhcloud.com:8000' });
app.get('/', function (req, res) {
res.sendfile('index.html');
});
io.on('connection', function (socket) {
socket.on('chatmessage', function (msg) {
console.log('index.js(socket.on)==' + msg);
io.emit('chatmessage', msg);
});
});
server.listen(process.env.OPENSHIFT_NODEJS_PORT, process.env.OPENSHIFT_NODEJS_IP);
Client(you can find complete source at https://github.com/varund29/openshift/blob/master/index.html)
src="http://nodejs-atnodejs.rhcloud.com:8000/socket.io/socket.io.js
src="http://code.jquery.com/jquery-1.11.1.js"
var socket = io.connect('http://nodejs-atnodejs.rhcloud.com:8000');
$('button').click(function (e) {
console.log('index.html($(button).click)=' + $('#m').val());
socket.emit('chatmessage', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chatmessage', function (msg) {
console.log('index.html(socket.on)==' + msg);
$('#messages').append($('<li>').text(msg));
});
Html body is
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" />
<button>Send</button>
</form>
When I ran your code I got the following errors in my log files on my gear on OpenShift Online:
Option log level is not valid. Please refer to the README.
Option polling duration is not valid. Please refer to the README.
So I commented out the following lines in your index.js file:
io.set('log level', 1); // reduce logging
io.set('transports', ['xhr-polling']);
io.set("polling duration", 10);
And it seems to be working fine now. You can test it here: http://nodejs-cdaley.rhcloud.com/
And you can view the code here: https://github.com/developercorey/nodejs
I am trying to follow along with a simple example of Socket.IO located at http://socket.io/get-started/chat/. So far I have the following code in my index.js file:
// INDEX.JS File
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendfile('index.html');
});
io.on('connection', function (socket) {
socket.on('chat message', function (msg) {
console.log('message: ' + msg);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
The error I am getting is:
The connection to ws://localhost:3000/socket.io/?EIO=2&transport=websocket&sid=i0SyiRvHJC1GUiafAAAC was interrupted while the page was loading.
I'm using FireFox to browse the page. It also doesn't work in Chrome.
Taking exactly your example works fine for me. I do get an error but not the same you are indicating (which is fine since this session does not exist here):
{
code: 1,
message: "Session ID unknown"
}
Is the index.html in the right path (visible by your app)?
I've set up a Ubuntu 10.04 server in my home network. I installed a lamp-server, NodeJs and Socket.io on it. It al seems to work fine but I can not make a connection from my client to the server. I think that I am missing the point of where to store the client files and/or how to the IP adress and port should be put in the code.
I'm using the example from David Walsh (http://davidwalsh.name/websocket). My ip-adress of the server is 192.168.1.113. On the client I store app.js in
/usr/local/bin
That is where node is installed as wel.
Server code
// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');
// Start the server at port 8000
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(8000);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
When I start the server with Node and enter the adress in a browser (http://192.168.1.113:8000) I see 'Hello Socket Lover!' so I guess this works fine.
I store my client file (client.html) in
/var/www
That is where the home folder of my LAMP server is.
Client.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket('http://192.168.1.113',{
port: 8000
});
socket.connect();
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
}
</body>
</html>
Now when I open this file in a browser (http://192.168.1.113/client.html) nothing happens. I see no connection on my Ubuntu server or other logs and there are no messages in the browser.
Ehmm... what am I doing wrong? I've tried for hours, changing all kind of things but still no result.
With the help of pmavik (see comments) my question is answered.
What I didn't know was how to serve the client file properly (index.html). I copied an example from www.socket.io, added the right ip-adress and port and now a connection is made.
The server file (app.js) and the client file (index.html) should be in the directory where Node is installed. The Node-server sends the client file to the browser so there is no need to put the client file in the /var/www directory where the 'normal' files for websites are.
app.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8000);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html
<html>
<head></head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.113:8000');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</body>
</html>