Skip to content
Advertisement

how to reply and send message after receive message in node js using websocket

After receive message from client, I have to connect db(mysql) and save data and need to response the result to client and inform to other(admin) client. So I need to get current socket client and special client(admin) from the socket list. Is it possible to get current socket outside of wss connection block? Thanks.

const WebSocketServer = require('ws');
 
// Creating a new websocket server
const wss = new WebSocketServer.Server({ port: 8080 });
const clients = new Map();
// Creating connection using websocket
wss.on("connection", ws => {
    console.log("new client connected");
    client_id = Date.now();
    clients.set(client_id, ws);
    // sending message
    ws.on('message', function(message) {
        //wss.broadcast(JSON.stringify(message));
        
        console.log('Received: ' + message);
        BuyCoin(message);
        //console.log()
      });
    ws.on("close", () => {
        console.log("the client has connected");
    });
    ws.onerror = function () {
        console.log("Some Error occurred")
    }
    // ws.send('You successfully connected to the websocket.');
});
function BuyCoin(strValue){
  const req_info = JSON.parse(strValue);
  console.log(req_info.user_id)
  console.log('betting!');
  var sql = 'SELECT * from users where id = ? LIMIT 1'
  connection.query(sql, req_info.user_id, (ws)=>{
      return function(err, rows, fields) {
        //console.log("ix="+ix);
        ws.send(rows[0]);
      };
  });
}
}

Advertisement

Answer

You have several options:

#1: You can put the BuyCoin function logic inside the ws scope to make it a local function that is in scope of the ws variable for the current connection like this:

const WebSocketServer = require('ws');

// Creating a new websocket server
const wss = new WebSocketServer.Server({ port: 8080 });
const clients = new Map();
// Creating connection using websocket
wss.on("connection", ws => {
    console.log("new client connected");
    client_id = Date.now();
    clients.set(client_id, ws);
    // sending message

    function BuyCoin(strValue) {
        const req_info = JSON.parse(strValue);
        console.log(req_info.user_id)
        console.log('betting!');
        var sql = 'SELECT * from users where id = ? LIMIT 1'
        connection.query(sql, req_info.user_id, (ws) => {
            return function(err, rows, fields) {
                //console.log("ix="+ix);
                ws.send(rows[0]);
            };
        });
    }

    ws.on('message', function(message) {
        //wss.broadcast(JSON.stringify(message));

        console.log('Received: ' + message);
        BuyCoin(message);
        //console.log()
    });
    ws.on("close", () => {
        console.log("the client has connected");
    });
    ws.onerror = function() {
        console.log("Some Error occurred")
    }
    // ws.send('You successfully connected to the websocket.');
});

#2: You can pass the ws value to your BuyCoin() function as an argument by just changing the function call from this:

BuyCoin(message);

to this:

BuyCoin(ws, message);

And, then changing your function declaration from this:

function BuyCoin(strValue) {...}

to this:

function BuyCoin(ws, strValue) {...}

Is it possible to get current socket outside of wss connection block?

No, there really is no such thing as the current socket. When using asynchronous code in nodejs, lots of different pieces of code can be “in-flight” at the same time so there is no global sense of the current socket. Instead, you have manage data specific to your current operation either by using scope, by passing as an argument or by setting as a properties on some other object that is passed as an argument. Since there is no natural object that BuyCoin() already has access to here that is specific to the user with the activity, then that leaves the first two options (using scope and passing as an argument).


FYI, this code looks a bit problematic because you’re allowing the webSocket to send in the user_id that will be operated on without any visible authentication. That exposes you to rogue sockets that can pretend to be users that they aren’t.

Also, it doesn’t appear you have code that removes webSockets from the clients Map object when they disconnect so that Map object will just get larger and larger and contain lots of dead connections.


Another thing that needs fixing is that your connection.query() code is declaring a callback that does nothing but return another function and it tried to make up a value of ws that would never actually be passed. That function you create inside the callback is never called. Change from this:

    connection.query(sql, req_info.user_id, (ws) => {
        return function(err, rows, fields) {
            //console.log("ix="+ix);
            ws.send(rows[0]);
        };
    });

to this:

    connection.query(sql, req_info.user_id, (err, rows, fields) => {
        //console.log("ix="+ix);
        ws.send(rows[0]);
    });

And, combine that with one of the above two solutions to get access to the ws value.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement