I'm trying to make an application on node.js using Soket.io
server-side
var server = http.createServer(app);
var io = require('socket.io')(server, {httpCompression: false, cookie: false});
io.on('connection', function(socket) { ... });
client-side
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var socket = io('ws://my-ws-server:8000/');
</script>
My problem:
Each client/user can write into console mysocket=io('ws://my-ws-server'); and push new connection, so now he can emit signals with wrong data or spam with new Socket connections
I also tried download socket.io.js code, edit it with $(function(){ /*socket.io code*/ });, and when include ../javascript/socket.io.js to my page, but it doesn't help, io() function still accessed from console
so, is there any solution? Is here any way to hide this function and prepare from spam with new fake socket connections?
tnx, sry for my eng.
One way is to prevent malicious data from your emit by validating input message before you dispatch it. So first check if it's a string your system knows about by comparing it to your dictionary, then correct authority level clearance. If it passes then do the callback which emits the registered action. It's not 100% but it prevents your application from taking malicious information
Related
I write a Node.Js app and I use Socket.Io as the data transfer system, so requests should be particular to per user. How can I make this?
My actual code;
node:
io.on('connection', (socket) => {
socket.on('loginP', data => {
console.log(data);
})
})
js:
var socket = io('',{forceNew : false});
$("#loginbutton").click(function() {
var sessionInfo = {
name : $("#login input[name='username']").val(),
pass : $("#login input[name='pass']").val()
}
socket.emit("loginP", sessionInfo)
})
It returns one more data for per request and this is a problem for me. Can I make this on Socket.Io or should I use another module, and If I should, which module?
If I understand your question correctly (It's possible I don't), you want to have just one connection from each user's browser to your nodejs program.
On the nodejs side, your io.on('connection'...) event fires with each new incoming user connection, and gives you the socket for that specific connection. So, keep track of your sockets; you'll have one socket per user.
On the browser side, you should build your code to ensure it only calls
var socket = io(path, ...);
once for each path (your path is ''). TheforceNew option is for situations where you have multiple paths from one program.
I have a JavaScript based active mq listener, who is using stomp and web sockets.I was able to send test messages to active mq and receive them.
What I really want is it needs to be sent from a Java based code.
Is it Ok to have the JavaScript listening on web sockets/stomp and
the java code be using tcp ?
If it is OK, should all of the ports be the same?
I am having issues receiving data in JavaScript. However I am seeing the topic being enquued in the active mq.thanks
function subscribeEndpoint(endpoint){
var client = Stomp.client("ws://localhost:61614/stomp", "v11.stomp");
var headers = { id:'JUST.FCX', ack: 'client'};
client.connect("admin", "admin", function () {
client.subscribe(endpoint,
function (message) {
alert(message);
}, headers);
});
}
Java:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616/stomp");
// Create a Connection
Connection connection = connectionFactory.createConnection();
connection.start();
// Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic)
Destination destination = session.createTopic("vrwrThreat");
// Create a MessageProducer from the Session to the Topic or Queue
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// Create a messages
TextMessage message = session.createTextMessage(text);
producer.send(message);
// Clean up
session.close();
connection.close();
Clients can communicate with each other across protocols and transport mechanisms without issue. A STOMP client on WebSocket or any other port (TCP, SSL, etc) can send to a Topic and an AMQP, MQTT or OpenWire client can receive the message so long as the protocol supports the content of the message, same goes for the reverse case of AMQP, MQTT or OpenWire sending and STOMP receiving.
The case you've mentioned is pretty standard. The code you've posted appears to be using the OpenWire client to send to a Topic "vrwrThreat". The URI used in the connection factory is slightly off in that you added the '/stomp' which is meaningless. Since you are sending to a Topic you need to ensure that the client that is to receive the message is active at the time of transmission otherwise the message will be dropped. Also you need to ensure that both are operating on the same Topic which is unclear from your code snippets.
I've seen many similar questions here, like this one about connecting servers to sockets, however, that doesn't seem to be working.
My goal is to have one of my server pages occasionally emit an "advance" event to all of the connected clients. My sockets server listener (sockets.js) looks like this
io.on('connection', function (socket) {
socket.on('advance', function () {
console.log('advancing clients');
io.emit('advance');
});
});
and my other server page (queue.js) has this code
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
I have also tried
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.emit('advance');
Both of those were in the other question I linked, however both of those failed. In the case of the first example, I received the error
socket.on is not a function
and on the second
socket.emit is not a function
it would seem that socket.connect worked, however, socket.on and socket.emit both failed. The idea is that queue.js will emit an event to all the clients, so they know to request the next song from the server.
As bonus points, I happen to be using passport.socketio to authenticate my users (though I don't seem to be getting the "ioAuthFail" message that would normally occur when a user attempts to connect and is not authenticated).
for what it's worth, my socket authentication code looks like
io.use(passportSocketIo.authorize({
//cookieParser:
key:'user',
secret:'secret',
store:new MongoStore({mongooseConnection:mongoose.connection}),
success:onAuthorizeSuccess,
fail:function(){console.log('ioAuthFail')}
}));
If there's a better way to advance the clients than using socket.io, i would also accept that, but for now it seems like this is the best way for me, assuming I can get this working.
EDIT
as mentioned through comments, changing my code to
var io = require('socket.io-client');
socket = io.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
socket.emit('advance');
doesn't break it, but it doesn't work, either.
I have a MEAN app setup with npm socket.io with expressjs and btford.socket-io on the client.
angular.module('myApp',['btford.socket-io'])
.factory('socket',function(socketFactory){
return socketFactory();
}
).controller('myAppCtrl',['$scope','socket',
function(a,b){
b.on('test',function(data){
console.log(data);
});
}
]);
Here's the node-express setup:
var app = express(),
server = app.listen(3000);
var socket = require('socket.io'),
io = socket.listen(server);
require('/config/routes/index.js')(app,io);
require('/config/routes/test.js')(app,io);
Routes : (config/routes/index.js)
module.exports = function(app,io){
app.get('/',function(req,res){
io.on('connection',function(socket){
socket.join(req.session._id);
});
res.render('index');
});
};
config/routes/test.js
module.exports = function(app,io){
app.get('/route1',function(req,res){
io.to(req.session._id).emit('test',{
data : 'Works'
});
res.render('route1');
});
};
A) Whenever the user goes to route1, the emit event is being fired and sent to all the users.
B) Is there a better approach to avoid using unique room for each user? This is not a chat application but rather implements push notifications
You have a couple major misunderstandings about how sockets and requests work. They are very separate operations and are not connected the way you appear to think they are. I will try to explain the problems with your code.
In this block of code:
module.exports = function(app,io){
app.get('/',function(req,res){
io.on('connection',function(socket){
socket.join(req.session._id);
});
res.render('index');
});
};
You are processing the / page request and EVERY time that request is hit, you add yet another event handler for io.on('connection', ...), thus you could have many of those.
Further, if the connection event happens BEFORE the user hits the / page, then you will miss it entirely and that socket will not be placed into the proper chat room.
Then, in this block of code:
module.exports = function(app,io){
app.get('/route1',function(req,res){
io.to(req.session._id).emit('test',{
data : 'Works'
});
res.render('route1');
});
};
io.to() takes a string that is the name of a chat room. So, this will send a message to every socket that is in the req.session._id chat room. For this to work, you'd have to make absolutely sure that req.session._id was completely unique to this user and that the desired user had already joined a chat room by this name. This could work, but it depends upon those specific things being correct.
You need to think of the connection from socket.io separately from a request. They are NOT tied together the way that you think they are. Your connection listener is for any connection not just a connection related to a given request... what you are trying to do simply will not work that way.
Imagine that your socket.io portions of your project are completely separate from the http requests in the web/express portions of your application. This is how you should think of passing messages.
Also worth consideration is that if you are using cluster or similar scaling methods, your default socket.io setup in one instance doesn't communicate with other instances.
I'm making an application where I need to map sockets to some object. I thought I would be safe using the socket.id variable provided by Socket.IO. Unfortunately while debugging I found out that the socket.id changed without the client disconnecting/reconnecting or whatever.
Here's a small piece of code to show what I'm trying to do:
var io = require('socket.io').listen(8080),
var myVariable = new Array();
// Main event loop
io.sockets.on('connection', function (socket) {
socket.on('myEvent', function(data) {
myVariable[socket.id] = data;
}
// 'someOtherEvent' which uses the mapped data.
socket.on('someOtherEvent', function(data) {
// Doesn't always work because socket.id has changed and var is empty
doSomethingWith(myVariable[socket.id]);
}
});
I'm not sure but I don't think this is the desired effect. Why does this happen and how would I work around it?
I was using node-inspector to debug my application and because I was holding the code on some breakpoint it disconnected the client (probably some timeout client side). That's why I got a new socket.id when I continued the code execution.
Looks like 'someOtherEvent' emited before 'myEvent' or socket has been reconnected. I use socket.id as connection identifier on two different projects in production and it works without any problems.