balderdashy / sails

Realtime MVC Framework for Node.js
https://sailsjs.com
MIT License
22.84k stars 1.95k forks source link

How to subscribe to user events (socket events) without using virtual get (for testing purposes) in sails.js #7119

Open hartatovich opened 3 years ago

hartatovich commented 3 years ago

Node version: 12.19.1 Sails version (sails): 1.4.0 ORM hook version (sails-hook-orm): 2.1.1 Sockets hook version (sails-hook-sockets): 2.0.0 Organics hook version (sails-hook-organics): 0.16.1 Grunt hook version (sails-hook-grunt): 4.0.1


I'm trying to implement some tests for my socket and I can't find a way to subscribe to User events without using sails.js virtual GET inside SailsSocket class

the application frontend code looks something like that

import socketIOClient from "socket.io-client";
import sailsIOClient from "sails.io.js";

const io = sailsIOClient(socketIOClient);
io.sails.transports = ['websocket'];
io.sails.url = "http://localhost:1337/";//define the url in http protocol (that's works fine)
io.sails.reconnectionAttempts = 10000;
const socket = io.sails.connect();

socket.get(`/api/v1/socket/subscribe/1`); //virtual GET to the server via the socket object (also fine)

and the backend sails.js code looks like this:

//routes.js

module.exports.routes = {
  'GET /api/v1/socket/subscribe/:user_id': {action: 'socket/subscribe'}
}

//socket/subscribe

fn: async function (inputs) {

    const id = this.req.param('user_id');
    const user = await User.findOne({id});
    User.subscribe(this.req, [user.id]);

}

so far so good and everything works pretty well on the application side.

my problem starts when i'm trying to connect with a different client side code on a socket class that don't have virtual GET I'm using k6, its a load testing tool with some API to connect to sockets.

I'm not sure if virtual GET is part of the web socket protocol or how everything really works around that with sails.js

//frontend code
io.sails.url = "http://localhost:1337/";

//k6 code 
var url = 'ws://localhost:1337/socket.io/?__sails_io_sdk_version=1.2.1&__sails_io_sdk_platform=node&__sails_io_sdk_language=javascript&EIO=3&transport=websocket';
var params = { tags: { my_tag: 'hello' } };
var response = ws.connect(url, params, function (socket) {
   socket.on('open', function open() {
      console.log('connected');
      socket.on('message', function (message) {
         console.log(`Received message: ${message}`);
      }); 
    });
  });

I changed the url to use the ws protocol (was originally http) and I managed to connect the socket from k6, however was not able to receive any user event that published on the backend

//publish event from the backend to the client
User.publish([1], data);

I can't figure out how to subscribe to those user events outside the client side code inside my application.. (k6 or any other socket library)

thanks for all those that spend the extra time reading all this! :)

some related links:

https://k6.io/docs/javascript-api/k6-ws/socket/

https://sailsjs.com/documentation/reference/web-sockets/socket-client/io-socket-get

https://sailsjs.com/documentation/reference/web-sockets/socket-client/sails-socket

sailsbot commented 3 years ago

@hartatovich Thanks for posting! We'll take a look as soon as possible.

In the mean time, there are a few ways you can help speed things along:

Please remember: never post in a public forum if you believe you've found a genuine security vulnerability. Instead, disclose it responsibly.

For help with questions about Sails, click here.

eashaw commented 3 years ago

Hi @hartatovich, We recommend writing an action to subscribe to the socket that recreates a JSON websocket response object. We also recommend taking a look at how sockets emit in the sails.io.js source code .