Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper EM reconnect support #14

Open
MmKolodziej opened this issue Nov 2, 2017 · 3 comments
Open

Proper EM reconnect support #14

MmKolodziej opened this issue Nov 2, 2017 · 3 comments

Comments

@MmKolodziej
Copy link

MmKolodziej commented Nov 2, 2017

Hey,
I've been having trouble while trying to setup proper reconnecting using your gem (using it through action_cable_client, but I believe that's irrelevant). Anyway, event machine supports reconnecting, but the method is not exposed in WebSocket::EventMachine::Client and due to this: eventmachine/eventmachine#218 implementing it is not straight forward.

This is what I've had to do in order to get stable reconnects:

require 'websocket-eventmachine-client'

EventMachine.run do
  ws = WebSocket::EventMachine::Client.connect(uri: 'ws://localhost:3000/websocket')

  ws.onclose do |code, reason|
    puts "Disconnected with status code: #{code}"
    EM.add_timer(2) do
      EventMachine.reconnect "localhost", 3000, ws
      ws.post_init
    end
  end
end

It should be pretty easy to remember the host and port and implement a simple reconnect method that will take care of firing post_init callback for the user. Let me know if this is something you'd like to see in your gem, I'll prepare a PR.

@imanel
Copy link
Owner

imanel commented Nov 2, 2017

Sounds awesome, I would love to see it implemented.

@h0jeZvgoxFepBQ2C
Copy link

@MmKolodziej did you make any progress on this?

@Dandush03
Copy link

here is my solution on this matter:

require 'websocket-eventmachine-client'
require 'forwardable'
require 'json'

class Websocket
  extend Forwardable

  ATTR_READER = %i[
    _websocket_client _uri _subscribed connection_tries
  ]

  ATTR_WRITER = %i[
    _subscribed connection_tries
  ]

  attr_reader *ATTR_READER

  attr_writer *ATTR_WRITER

  def initialize(uri:, params:, connect_on_start: true, headers: {}, tls: {})
    @_uri = uri
    @connection_tries = 0
    @_subscribed = false
    # @_message_factory = MessageFactory.new(params)
    @_websocket_client = WebSocket::EventMachine::Client.connect(uri: @_uri, headers: headers, tls: tls)

    connect!(headers, tls) if connect_on_start
  end

  def connect!(headers = {}, tls = {})
    _websocket_client.onopen do
      self.connection_tries += 1
      puts "Connected"
      puts "Connection attempt #{connection_tries}"
    end

    _websocket_client.onclose do |code, reason|
      puts "Disconnected with status code: #{code}"
      self._subscribed = false
      _disconnected_callback&.call
    end

    _websocket_client.onmessage do |msg, type|
      if msg.include?('disconnect')
        message = JSON.parse(msg)
        if message['reconnect'] == true
          puts "reconnecting to server please wait..."
          EM.add_timer(3) do
            EventMachine.reconnect "app.example.dev", 443, _websocket_client
            _websocket_client.post_init
          end
        else
          puts "proceeding to disconnect"
        end
      else
        puts "Received message: #{msg}"
      end
    end
  end
end

# Then we can use it by calling it like this
EventMachine.run do
  uri = "wss://app.example.dev/cable"
  client = Websocket.new(uri: uri, params: 'ClientUserChannel', headers: {
    'Authorization' => "Token token=#{token}" # If needed
  })
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants