Extra params with socket.io - javascript

How can I send extra parameters with the connection in socket.io? So when a client connects, they send additional information, and server-side it is received as
io.on('connection', function(client, param1, param2, param3) {
// app code
}

Here's a little trick which should work. First, you create your own Socket client that sends a message on first connection (containing all your additional info).
// Client side
io.MySocket = function(your_info, host, options){
io.Socket.apply(this, [host, options]);
this.on('connect', function(){
this.send({__special:your_info});
});
};
io.util.inherit(io.MySocket, io.Socket);
var my_info = {a:"ping"}
var socket = io.MySocket(my_info);
Then on the server side, you modify your socket to listen for the special message and fire off an event when it does.
// Server side
var io = require('socket.io').listen(app);
io.on('connection', function(client){
client.on('message', function(message){
if (message.__special) {
io.emit('myconnection', client, message.__special);
}
});
});
io.on('myconnection', function(client, my_info) {
// Do your thing here
client.on('message', ...); // etc etc
}
This is the technique I used to link my session handling into Socket.IO for a package I wrote.

Related

Accessing an outside variable inside a javascript event

I'm building a server which acts as a proxy between a browser and a third party service using websockets. the general sequence is
Browser connects to server via websocket
After authentication , the server connects via websocket to a third party service.
the third party service sends a message to the server which relays it back to the browser
One problem i'm trying to solve is to disconnect the websocket from server -> third party service whenever the socket from the browser disconnects.
To that extent, i'm thinking of maintaining an object like the below
var thirdPartySockets = {};
whenever a client socket connects :
var ServerSocket = connectToThirdParty (clientSocketId, URL);
thirdPartySockets [clientSocketId] = ServerSocket;
The code for connectToThirdParty
var connectToThirdParty = function(clientSocketId, URL){
var client = new WebSocketClient();
client.on('connectFailed', function(err) {
console.log('connection failed')
});
client.on('connect', function(connection) {
connection.on('error', function(err) {
});
connection.on('close', function() {
// attempt reconnection
});
connection.on('message', function(message) {
// send back to client
});
});
client.connect(URL);
return client
}
The problem here is i'm trying to disconnect the server socket whenever the browser socket disconnects. I cannot seem to access the thirdPartySocket list object in the disconnect event.
var thirdPartySockets = {};
io.on('connection', function(socket){
socket.on('disconnect', function(){
// how do i access the thidPartySockets object here?
});
});
Are there better ways to handle this situation?

JS Socket | Add full array on the site

So I have a kinda bug on my socket system. I have a array which will be emited if new connection is made to the site, but the problem is that it will be called on all users. So if I have there console.log('new user') then everyone will receive it to the console. My question is, how can I do it so the only one user who just connected receives only it?
Here is my server
io.on('connection', function(client){
clients.push(client.id);
io.emit('add games', coinflips); //This is the line
console.log(clients);
client.on('disconnect', function(){
clients.splice(client.indexOf, 1);
console.log(clients);
});
});
Here is how it's being handled
socket.on('add games', function(data){
if(data.length > 0){
addGames(data);
}
});
you can use the the socket id, socket.id then send to that id.
something along this line.
io.of('/mynamespace').sockets[socketID].emit(...)
Event this logic could work
clients = [];
then whenever a connection is made.
clients.push(socket);
then in the clients array, just index it.
clients[0].emit(...)
this is how you get a id upon connection.
console.info('Client id (id=' + socket.id + ').');
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
Namespaces are useful features to minimize the number of resources (TCP connections) and at the same time separate concerns within your application by introducing separation between communication channels. Multiple namespaces actually share the same WebSockets connection thus saving us socket ports on the server.
Namespaces are created on the server side. But they are joined by clients by sending a request to the server.
---------------------------------------------------------------
Default Namespaces
The root namespace '/' is the default namespace which is joined by clients if a namespace is not specified by the client while connecting to the server. All connections to the server using the socket object client side are made to the default namespace.
--------------------------------------------------------
Custom Namespaces
We can create our own custom namespaces. To set up a custom namespace, we can call the of function on the server-side:
---------------------------------------------------------
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');
});
var nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
nsp.emit('hi', 'Hello everyone!');
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});

How to call a function from outside the object

I am trying to make a proxy between sockets and websockets. I receive requests on socket server and I want to proxy them to websocket clients, however websocket.ws.send appears to be undefined. What would be the correct way of doing this? How to call ws.send() from outside of the object?
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({port: 8001}),
var net = require('net')
websocket = wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('received: %s', message);
});
ws.send("NEW USER JOINED");
});
var socketServer = net.createServer(function(socket) {
socket.on("data", function(data){
console.log("Received: "+data)
websocket.ws.send("Message")
});
});
socketServer.listen(1337, '127.0.0.1');
The problem you have is that ws is a single web socket for one connection. It is not a property on the websocket object, but an argument to a callback you define. Each time someone connects you will get a connection event which will execute your callback, allowing you to bind a function to that specific web socket for the message event.
You either need to store the ws object in a variable that the socket server can access or you could broadcast to all clients.
wss.clients.forEach(function each(client) {
client.send(data);
});
This will work fine if you only have one client, however if you have multiple connections to both the websocket and socket server then you need to use a method of identifying connections on both so that you can locate the websocket connection you need to send data to.

socket.io not emitting event from server to client on connection

I have a very basic setup with socket.io but am having trouble getting my server to send back a message once the connection has been established.
When a connection is established to my server, I want the server to send back a message to the client. I've tried to accomplish this with the following code:
Server
// Modules
var fs = require('fs');
var https = require('https');
// Certificate
var options = {
pfx: fs.readFileSync('<my cert>')
};
// Create Server
httpsServer = https.createServer(options);
// Create websocket
var io = require('socket.io')(httpsServer);
// Listen on a port
httpsServer.listen(4000,function() {
console.log('listening on *:4000');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.emit('test','you connected');
});
Client
var socket = io('https://<my server>:4000');
When I execute this code, the websocket gets established and my server console shows the message "a user connected". However, the message ['test','you connected'] does not get emitted through the socket.
The only way I've been able to get this to work is to use setTimeout() to wait 500ms before emitting the event, in which case it does work.
Why is that? How can I configure my server to automatically respond with a message as soon as the user connects?
You need to listen to the emitted event, using socket.on(event, callback);
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var socket = io('https://localhost:4000');
//test is the emitted event.
socket.on("test", function(data){
console.log(data); //"you connected"
});
</script>

How can I get the socket ID from an event in Socket.io?

I want to know which client sent an event when it arrives on the server. For example:
var socket = require(socket.io')(port);
socket.on("ask question", function(data){
var socketid = // ?
//respond to sender
socket.sockets.connected[socketid].emit("Here's the answer");
});
How can I get the socket ID of the event sender?
Your server-side logic is a bit off. The client connects and that's where the client socket is revealed and that's where you listen to events from a particular client. Usually, it would look like this:
var io = require("socket.io")(port);
io.on('connection', function (socket) {
socket.on('ask question', function (data) {
// the client socket that sent this message is in the
// socket variable here from the parent scope
socket.emit("Here's the answer");
});
});
This is shown in the socket.io docs here.

Categories