Kyle Werner
Kyle Werner

Reputation: 280

List of active websocket connections with puma and tubesock

I'm using Puma and Tubesock for websocket messages and would like to access a list of connected websockets inside a library file that handles sending messages. What I am trying to do is check if the user is connected through a websocket and if not send the message through a push notification.

The user connects to the websocket with a path containing their userid:

# config/routes.rb
Rails.application.routes.draw do
  get 'ws/:user_id', to: 'socket#ws', as: :socket
end

and uses Tubesock inside the controller

class SocketController < ApplicationController
  include Tubesock::Hijack

  def ws
    hijack do |tubesock|
      @wsTube = tubesock

      tubesock.onopen do
        socket_user = User.find_by_user_id(params[:user_id])
        # setup to send/receive messages through /lib/notification.rb
      end

      tubesock.onclose do
        # cleanup when connection closes
      end
    end
  end
end

I thought about adding a property to the user in the database but I'm worried if the connection abruptly ends, like during a reboot, then that property would say connected when if fact it is not. Ideally I want to inspect active connections and not toggle a property during open and close.

Upvotes: 1

Views: 609

Answers (1)

Myst
Myst

Reputation: 19221

Considering your issue, rather than the title of your question, it seems to me you should only mark a message as 'read' if Tubesock#send_data returns a truthful value.

Reading the source code it seems that Tubesock#send_data will return either a number if successful or nil if failed (be aware that it might return an undetermined value if the websocket has onclose callbacks).

As to storing the Tubesock socket in the Database, that is simply impossible, as the Tubesock contains the socket object which is an open file descriptor and cannot be stored in a persistent manner to a database.

You should probably store the data in the local memory, such an in a Hash.

If Tubesock were to support connection's UUIDs, that would be a different story which would also allow you to scale up from a single process and use Redis... but taking a quick look (I'm not a Tubesock user), this doesn't seem the case.

Upvotes: 1

Related Questions