I have this socket.io server:
var io = require('C:\\Program files\\nodejs\\node_modules\\socket.io').listen(55555);
io.set('destroy upgrade', false);
io.sockets.on('connection', function (socket) {
socket.on('sayHello', function () {
console.log('Hello client!');
socket.emit('sayHello');
});
socket.on('disconnect', function () {
console.log('Goodbye!');
});
});
And I want to connect to the server using the WebSocket class like this:
var socket = new WebSocket('ws://localhost:55555');
I get the connection, but I want to know how can I call an event of the server, example: "sayHello", is that possible? or does Socket.IO use some kind of token in order to avoid spoofing? Thank you!
You should be able to use the socket.io-client module directly from node. It handles the socket.io protocol and everything for you, just like the browser, except in node.
Related
I have a node.js server and I attached socket.io listener to it. The code is like this.
const server = new Hapi.Server();
server.connection({
"port": config.port
});
let io = socketio(server.listener);
io.on("connection", function(socket) {
console.log("A user connected");
socket.on("disconnect", function(){
console.log("A user disconnected");
});
// receive message from client
socket.on("client-server", function(msg) {
console.log(msg);
});
});
// somewhere to emit message
io.emit("server-client", "server to client message");
Normally I use the standard way to connect to the websocket server. An example is like this:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('server-client', function(data) {document.write(data)});
socket.emit('client-server', 'test message');
</script>
<body>Hello world</body>
</html>
It works without issue. Now, my colleague wants to connect to the websocket server from his FME server. Based on his research, the only way he can use to connect to a websocket server is using a url like this:
ws://localhost:3000/websocket
My question is: is there a way to connect to socket.io server listener using this type of string?
If not, is there a way to create a websocket server with ws://host:port url and also attach it to my node.js server?
Or, is there a way to connect to socket.io listener in FME server?
To tell Socket.IO to use WebSocket only, add this on the server:
io.set('transports', ['websocket']);
And on the client add this:
var socket = io({transports: ['websocket']});
Now you can only connect to the WebSocket server using ws protocol.
I have this scenario with socket.io:
I want to receive the data from a sever and Forward the data to webclient.But when I receive a lot of data and close the page, it console
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
...(a lot)
Here is the code:
server:
var express=require('express');
var app=express();
var net=require('net');
var http=require('http').createServer(app);
var io=require('socket.io')(http);
var net=require('net');
var nodeServer = new net.Socket();
var aSocket=null;
io.on('connection', function (socketIO) {
aSocket=socketIO;
};
nodeServer.on('data', function(data) {
if(aSocket!=null){
aSocket.emit('pushToWebClient',useData);
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
}
client:
socket.on('pushToWebClient', function (useData) {
});
I find
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
console a lot of'DISCONNECTED FROM CLIENT' but actually it should console just once in the code.
I had even console.log(aSocket.id),it console just only one.
I don't know why it is console so many times.
I haved used setMaxListeners(10) to try to avoid it .
Will it lead to a memory leak?
It appears that you are registering multiple event listeners for the same disconnect event. In this code:
nodeServer.on('data', function(data) {
if(aSocket!=null){
aSocket.emit('pushToWebClient',useData);
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
}
You appear to be registering a new disconnect event listener every time you get a data message. So, if you have multiple listeners, then each one will get called when the socket disconnects and the result is that you will log the same message multiple times all for the same socket.
You can verify this is what is happening by moving your disconnect handler into the connection handler so it is only ever attached just once for each socket.
In addition putting asocket into a global or module-level variable means that your server code would only ever work with one single client at a time. It is not clear exactly what you are trying to do when you get data on the nodeserver connection - whether you're trying to send that data to only one specific client or to all connected clients.
I try to delete the code:
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
or moving it out of nodeServer handler,
it turn into normal and never suggest me to setMaxlisener.
I think maybe it is incorrect put one API into a API
And the envent maybe not release the socket,so it console multiple times .
EDIT: I'm moving this to the top because I saw that someone already provided my solution but you were having a problem managing the data sent to the client. Your aSocket variable will be overwritten by every new client that connects to your app. If you want to send data to a specific client using your server nodeServer, you should create a global variable (an array) that keeps track of all of your client socket connections. So instead of using one global variable aSocket do the following:
var net=require('net');
var nodeServer = new net.Socket();
var clients = [];
io.on('connection', function (socketIO) {
clients.push(socketIO);
var clientNum = clients.length-1;
aSocket.on('disconnect', function () {
clients.splice(clientNum, 1);
console.log('DISCONNECTED FROM CLIENT: '+socketIO.id);
});
};
nodeServer.on('data', function(data) {
//have your data object contain an identifier for the client that caused the handler to fire
//for the sake of the answer I just use data.id
var clientID = data.id;
if(clients[clientID]!=null){
clients[clientID].emit('pushToWebClient', useData);
}
}
Let me know how it goes! My original answer is below:
Try moving
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
out of your nodeServer.on('data', ...) event listener into the io.on('connection', ...) event listener like so:
io.on('connection', function (socketIO) {
aSocket=socketIO;
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
};
socket.io is designed to keep polling for the presence of the server/client. If either the server or the client are disconnected, the remaining 'side' continues to receive polling requests and, consequently, will continuously print an error.
You can see this effect on the client side in your browser when you disconnect your server and leave the client page open. If you look at the browser's error/console log what you should see is a continuous stream of net::ERR_CONNECTION_REFUSED errors. By placing the disconnect event handler in the .on('data', ...) handler for your server, you are seeing the converse of this situation.
net:ERR_CONNECTION_REFUSED example
This is basic code for socket.io
The following example attaches socket.io to a plain Node.JS HTTP
server listening on port 3000.
var server = require('http').createServer();
var io = require('socket.io')(server);
io.on('connection', function(client){
client.on('event', function(data){});
client.on('disconnect', function(){});
});
server.listen(3000);
I think, you should try.
Am not able to call socket-client listener using sails.sockets.js onConnect event on server side..
E.g
onConnect: function(session, socket) {
socket.on('chat message', function(msg){
console.log(msg);
console.log("socket.id: " + socket.id);
sails.sockets.broadcast(socket.id, 'chat message', {msg:msg});
});
}
Please let me know whats the correct way of calling back to your socket-client using socket-server events like onConnect..
If you are using standard sails.js socket library:
$(document).ready(function() {
io.socket.on('connect', function() {
});
io.socket.on('chat message', function(data) {
io.socket.post('/routeToAction', {
}, function(data, jwres) {
});
});
});
for newer version, you have to use config/bootstrap.js file for listen events
module.exports.bootstrap = function(cb) {
// handle connect socket first event executes after logged in
sails.io.on('connect', function (socket){
// store facebook token here
});
// handle custom listener for other stuff
sails.io.on('doSomeStuff', function (socket){
// check facebook token match with requested token
});
cb();
};
client : you can simple emit "doSomeStuff" after logged in with facebook and pass token with each request
Finally am become little expert in web sockets who knows back anf forth of push technoligy via websockets..
How to start with websockets :
Step 1: Choose any websocket framework for your application and install socket client on client side and socker server on server side with listeners(imp.).
Step 2: Once you are ready with socket setup on both sides then your client/browser will make a connection after every page load which is listened on server side via onConnect listener or event.
Step 3: Successfull connection on both sides giving you socket object which contains each client socket id which is managed at server side to either join any channel/room or just to make a broadcast or blast.
Remember:
i. Socket object is responsible for defining listeners on both client side and server side. Using socket object you can pass any data to listeners.
ii. Socket connection is very helpful when you trying to push data from client to server and vice-versa.
iii. You can make your small chatter tool with it once you understand as mentioned above.
Will share similar working snippet soon..
//onConnect event on server side
onConnect: function(session, socket) {
console.log("Socket Connect Successfully: " + socket.id );
socket.on('chatAgency', function(data){
sails.sockets.broadcast(data.agencyId,"chatAgency", {message:data.message,agencyId:session.agencyId});
});
},
I just started up learning how to make web applications. I am making a webserver in nodejs (a to-do list app). I am using the express framework, and mongodb as database. For communication between the client and the server i am using socket.io.
I can't find a way to make it so that when the server emits and event the client will update the info on all of his open windows of the page. Right now the info updates only on the window that triggered the event on ther server. This is the server code:
Server code:
var io = require('socket.io').listen(server);
io.of('/home').on('connection', function (socket) {
socket.on('newListGroup', function (data) {
...
socket.emit('groupNo', obj);
});
}); `
Client javascript:
var socket = io.connect('http://localhost/login');
socke.on('groupNo', function(data){ ... });
$('#newListGroup').blur(function() {
socketLogin.emit('newListGroup', {newGroup:newGroup});
});
Can this work or should I take another approach?
You can broadcast a message to all sockets like this:
var io = require('socket.io').listen(server);
io.of('/home').on('connection', function (socket) {
socket.on('newListGroup', function (data) {
socket.broadcast.emit('groupNo', obj); });
});
It should be limited to the namespace but you will probably have to implement your own logic for broadcasting only to windows on the same client (probably using authentication) if that is what you want to do.
Is there something that I can do on the client side to detect that the socket.io websocket is not available? Something along the lines of:
server starts as per usual
clients connect
messages are sent back and forth between server and client(s)
server shuts down (no longer available)
warn the connected clients that the server is not available
I tried to add the 'error' and 'connect_failed' options on the client side but without any luck, those didn't trigger at all. Any ideas from anyone how I can achieve this?
The disconnect event is what you want to listen on.
var socket = io.connect();
socket.on('connect', function () {
alert('Socket is connected.');
});
socket.on('disconnect', function () {
alert('Socket is disconnected.');
});
If you want to be able to detect that the client was not able to connect to the server, then try using connect_error. This works for me with socket.io-1.3.5.js. I found this in https://stackoverflow.com/a/28893421/2262092.
Here's my code snippet:
var socket = io.connect('http://<ip>:<port>', {
reconnection: false
});
socket.on('connect_error', function() {
console.log('Failed to connect to server');
});
hit this bug during my development and noticed my event calls were doubling up every time i reset the server, as my sockets reconnected. Turns out the solution that worked for me, which is not duping connections is this
var socket = io.connect();
socket.on('connect', function () {
console.log('User connected!');
});
socket.on('message', function(message) {
console.log(message);
});
( Found this at https://github.com/socketio/socket.io/issues/430 by KasperTidemann )
Turns out, it was becuase I put the 'message' listener inside the 'connect' function. Seating it outside of the listener, solves this problem.
Cheers to Kasper Tidemann, whereever you are.
Moving on!!
connect_error didn't work for me (using Apache ProxyPass and returns a 503).
If you need to detect an initial failed connection, you can do this.
var socket;
try {
socket = io();
}
catch(e) {
window.location = "nodeServerDown.php";
}
Redirects the user to a custom error page when the server is down.
If you need to handle a disconnect after you've connected once.
You do this:
socket.on('disconnect', function() {
//whatever your disconnect logic is
});