class ScClient

Class ScClient provides an interface to connect to the socketcluster server

@author Maanav Shah <shahmaanav07@gmail.com>

Attributes

max_attempts[RW]
max_reconnect_interval[RW]
reconnect_interval[RW]

Public Class Methods

new(url) click to toggle source

Initializes instance variables in socketcluster client

@param [String] url ScServer connection URL

# File lib/sc_client.rb, line 29
def initialize(url)
  @id = ''
  @cnt = 0
  @url = url
  @acks = {}
  @channels = []
  @enable_reconnection = false
  @delay = 3
  initialize_emitter
  initialize_reconnect
  initialize_logger
end

Public Instance Methods

ack_block(cid) click to toggle source

Acknowledment block to be executed on event

@param [String] cid @cnt id received from ScServer

@return [Lambda] Acknowledgment to be sent to ScServer

# File lib/sc_client.rb, line 108
def ack_block(cid)
  ws = @ws
  lambda do |error, data|
    ws.send(get_ack_object(error, data, cid))
  end
end
connect() click to toggle source

Connects to the ScServer

# File lib/sc_client.rb, line 121
def connect
  EM.epoll

  EM.run do
    trap('TERM') do
      @enable_reconnection = false
      disconnect
    end

    trap('INT') do
      @enable_reconnection = false
      disconnect
    end

    @ws = WebSocket::EventMachine::Client.connect(uri: @url)

    @ws.onopen do
      reset_value
      @ws.send(get_handshake_object(increment_cnt).to_json)
      @on_connected.call if @on_connected
    end

    @ws.onmessage do |message, _type|
      @logger.info("Message received : #{message}") if @logger
      if message == ''
        @logger.info("Ping received, sending PONG back")
        @ws.send('')
      else
        main_object = JSON.parse(message)
        data_object = main_object['data']
        rid = main_object['rid']
        cid = main_object['cid']
        event = main_object['event']
        result = Parser.parse(event, rid)
        if result == Parser::CHECK_AUTHENTICATION
          if @on_authentication
            @id = data_object['id']
            @on_authentication.call(self, data_object['isAuthenticated'])
          end
          subscribe_channels
        elsif result == Parser::PUBLISH
          execute(data_object['channel'], data_object['data'])
        elsif result == Parser::REMOVE_AUTHENTICATION
          @auth_token = nil
        elsif result == Parser::SET_AUTHENTICATION
          if @on_set_authentication
            @on_set_authentication.call(self, data_object['token'])
          end
        elsif result == Parser::EVENT
          if haseventack(event)
            executeack(event, data_object, ack_block(cid))
          else
            execute(event, data_object)
          end
        else # Parser::ACKNOWLEDGEMENT
          tuple = @acks[rid] if @acks.include?(rid)
          if tuple
            ack = tuple[1]
            ack.call(tuple[0], String(main_object['error']), String(main_object['data']))
          end
        end
      end
    end

    @ws.onerror do |error|
      @on_connect_error.call(error) if @on_connect_error
    end

    @ws.onclose do
      if should_reconnect
        @reconnect_interval = @max_reconnect_interval if @reconnect_interval > @max_reconnect_interval
        sleep(@reconnect_interval / 1000)
        @attempts_made += 1
        @logger.info("Attempting to reconnect : #{@attempts_made}") if @logger
        connect
      else
        stop
      end
    end

    def stop
      EventMachine.stop
    end
  end
end
disconnect() click to toggle source

Disconnects the connection with ScServer

# File lib/sc_client.rb, line 235
def disconnect
  @on_disconnected.call if @on_disconnected
  @enable_reconnection = false
  @ws.close
end
emit(event, object) click to toggle source

Emits the specified event on the corresponding server-side socket

@param [String] event Event @param [String] object Data for the specified event

# File lib/sc_client.rb, line 249
def emit(event, object)
  @ws.send(get_emit_object(event, object).to_json)
end
emitack(event, object, ack) click to toggle source

Emits the specified event on the corresponding server-side socket with acknowledgment

@param [String] event Event @param [String] object Data for the specified event @param [Lambda] ack Block to execute on event acknowledgment

@return [<type>] <description>

# File lib/sc_client.rb, line 262
def emitack(event, object, ack)
  @ws.send(get_emit_ack_object(event, object, increment_cnt).to_json)
  @acks[@cnt] = [event, ack]
end
publish(channel, data) click to toggle source

Publish data to the specified channel name

@param [String] channel A channel name @param [String] data Data to be published on the channel

# File lib/sc_client.rb, line 327
def publish(channel, data)
  @ws.send(get_publish_object(channel, data, increment_cnt).to_json)
end
publishack(channel, data, ack) click to toggle source

Publish data to the specified channel name

@param [String] channel A channel name @param [String] data Data to be published on the channel @param [Lambda] ack Block to execute on publish acknowledgment

# File lib/sc_client.rb, line 340
def publishack(channel, data, ack)
  @ws.send(get_publish_object(channel, data, increment_cnt).to_json)
  @acks[@cnt] = [channel, ack]
end
set_auth_token(token) click to toggle source

Method to set the authentication token

@param [String] token Authentication token provided by ScServer

# File lib/sc_client.rb, line 77
def set_auth_token(token)
  @auth_token = token.to_s
end
set_authentication_listener(on_set_authentication, on_authentication) click to toggle source

Adds handler for authentication

@param [Lambda] on_set_authentication Block to set authentication token @param [Lambda] on_authentication Block to execute on authentication

# File lib/sc_client.rb, line 65
def set_authentication_listener(on_set_authentication, on_authentication)
  @on_set_authentication = on_set_authentication
  @on_authentication = on_authentication
end
set_basic_listener(on_connected, on_disconnected, on_connect_error) click to toggle source

Adds handler for connect, disconnect and error

@param [Lambda] on_connected Block to execute on connected @param [Lambda] on_disconnected Block to execute on disconnected @param [Lambda] on_connect_error Block to execute on connection error

# File lib/sc_client.rb, line 51
def set_basic_listener(on_connected, on_disconnected, on_connect_error)
  @on_connected = on_connected
  @on_disconnected = on_disconnected
  @on_connect_error = on_connect_error
end
set_delay(delay) click to toggle source

Set the delay for reconnection to ScServer

@param [Integer] delay Delay in seconds to reconnect

# File lib/sc_client.rb, line 214
def set_delay(delay)
  @delay = delay
end
set_reconnection(enable) click to toggle source

Allows to reconnect to ScServer

@param [Boolean] enable True to reconnect to server, False to disconnect

# File lib/sc_client.rb, line 225
def set_reconnection(enable)
  @enable_reconnection = enable
end
stop() click to toggle source
# File lib/sc_client.rb, line 201
def stop
  EventMachine.stop
end
subscribe(channel) click to toggle source

Subscribes to a particular channel

@param [String] channel A channel name

# File lib/sc_client.rb, line 274
def subscribe(channel)
  @ws.send(get_subscribe_object(channel, increment_cnt).to_json)
  @channels << channel unless @channels.include?(channel)
end
subscribe_channels() click to toggle source

Subscribe all the channels available

# File lib/sc_client.rb, line 97
def subscribe_channels
  @channels.each { |channel| subscribe(channel) }
end
subscribeack(channel, ack) click to toggle source

Subscribes to a particular channel with acknowledgment

@param [String] channel A channel name @param [Lambda] ack Block to execute on subscribe acknowledgment

# File lib/sc_client.rb, line 287
def subscribeack(channel, ack)
  @ws.send(get_subscribe_object(channel, increment_cnt).to_json)
  @channels << channel
  @acks[@cnt] = [channel, ack]
end
subscribed_channels() click to toggle source

Get the list of all subscribed channels

# File lib/sc_client.rb, line 87
def subscribed_channels
  @channels
end
unsubscribe(channel) click to toggle source

Unsubscribes to a particular channel

@param [String] channel A channel name

# File lib/sc_client.rb, line 300
def unsubscribe(channel)
  @ws.send(get_unsubscribe_object(channel, increment_cnt).to_json)
  @channels.delete(channel)
end
unsubscribeack(channel, ack) click to toggle source

Unsubscribes to a particular channel with acknowledgment

@param [String] channel A channel name @param [Lambda] ack Block to execute on unsubscribe acknowledgment

# File lib/sc_client.rb, line 313
def unsubscribeack(channel, ack)
  @ws.send(get_unsubscribe_object(channel, increment_cnt).to_json)
  @channels.delete(channel)
  @acks[@cnt] = [channel, ack]
end

Private Instance Methods

increment_cnt() click to toggle source

Increments the value of @cnt

# File lib/sc_client.rb, line 363
def increment_cnt
  @cnt += 1
end
reset_value() click to toggle source

Resets the value of @cnt

# File lib/sc_client.rb, line 353
def reset_value
  @cnt = 0
end