class PusherClient::Socket

Constants

CLIENT_ID

Mimick the JavaScript client

VERSION

Attributes

channels[R]
connected[R]
encrypted[RW]
global_channel[R]
path[R]
secure[RW]
socket_id[R]

Public Class Methods

new(application_key, options={}) click to toggle source
# File lib/pusher-client/socket.rb, line 15
def initialize(application_key, options={})
  raise ArgumentError if (!application_key.is_a?(String) || application_key.size < 1)

  @path = "/app/#{application_key}?client=#{CLIENT_ID}&version=#{VERSION}"
  @key = application_key
  @secret = options[:secret]
  @socket_id = nil
  @channels = Channels.new
  @global_channel = Channel.new('pusher_global_channel')
  @global_channel.global = true
  @secure = false
  @connected = false
  @encrypted = options[:encrypted] || false

  bind('pusher:connection_established') do |data|
    socket = JSON.parse(data)
    @connected = true
    @socket_id = socket['socket_id']
    subscribe_all
  end

  bind('pusher:connection_disconnected') do |data|
    @channels.channels.each { |c| c.disconnect }
  end

  bind('pusher:error') do |data|
    PusherClient.logger.fatal("Pusher : error : #{data.inspect}")
  end
end

Public Instance Methods

[](channel_name) click to toggle source
# File lib/pusher-client/socket.rb, line 109
def [](channel_name)
  if @channels[channel_name]
    @channels[channel_name]
  else
    @channels << channel_name
  end
end
authorize(channel, callback) click to toggle source

auth for private and presence

# File lib/pusher-client/socket.rb, line 124
def authorize(channel, callback)
  if is_private_channel(channel.name)
    auth_data = get_private_auth(channel)
  elsif is_presence_channel(channel.name)
    auth_data = get_presence_auth(channel)
    channel_data = @user_data
  end
  # could both be nil if didn't require auth
  callback.call(channel, auth_data, channel_data)
end
authorize_callback(channel, auth_data, channel_data) click to toggle source
# File lib/pusher-client/socket.rb, line 135
def authorize_callback(channel, auth_data, channel_data)
  send_event('pusher:subscribe', {
    'channel' => channel.name,
    'auth' => auth_data,
    'channel_data' => channel_data
  })
  channel.acknowledge_subscription(nil)
end
bind(event_name, &callback) click to toggle source
# File lib/pusher-client/socket.rb, line 104
def bind(event_name, &callback)
  @global_channel.bind(event_name, &callback)
  return self
end
connect(async = false) click to toggle source
# File lib/pusher-client/socket.rb, line 45
def connect(async = false)
  if @encrypted || @secure
    url = "wss://#{HOST}:#{WSS_PORT}#{@path}"
  else
    url = "ws://#{HOST}:#{WS_PORT}#{@path}"
  end
  PusherClient.logger.debug("Pusher : connecting : #{url}")

  @connection_thread = Thread.new {
    options = {:ssl => @encrypted || @secure}
    @connection = WebSocket.new(url, options)
    PusherClient.logger.debug "Websocket connected"
    loop do
      msg = @connection.receive[0]
      params  = parser(msg)
      next if (params['socket_id'] && params['socket_id'] == self.socket_id)
      event_name   = params['event']
      event_data   = params['data']
      channel_name = params['channel']
      send_local_event(event_name, event_data, channel_name)
    end
  }

  @connection_thread.run
  @connection_thread.join unless async
  return self
end
disconnect() click to toggle source
# File lib/pusher-client/socket.rb, line 73
def disconnect
  if @connected
    PusherClient.logger.debug "Pusher : disconnecting"
    @connection.close
    @connection_thread.kill if @connection_thread
    @connected = false
  else
    PusherClient.logger.warn "Disconnect attempted... not connected"
  end
end
get_presence_auth(channel) click to toggle source
# File lib/pusher-client/socket.rb, line 158
def get_presence_auth(channel)
  string_to_sign = @socket_id + ':' + channel.name + ':' + @user_data
  signature = HMAC::SHA256.hexdigest(@secret, string_to_sign)
  return "#{@key}:#{signature}"
end
get_private_auth(channel) click to toggle source
# File lib/pusher-client/socket.rb, line 152
def get_private_auth(channel)
  string_to_sign = @socket_id + ':' + channel.name
  signature = HMAC::SHA256.hexdigest(@secret, string_to_sign)
  return "#{@key}:#{signature}"
end
is_presence_channel(channel_name) click to toggle source
# File lib/pusher-client/socket.rb, line 148
def is_presence_channel(channel_name)
  channel_name.match(/^presence-/)
end
is_private_channel(channel_name) click to toggle source
# File lib/pusher-client/socket.rb, line 144
def is_private_channel(channel_name)
  channel_name.match(/^private-/)
end
send_event(event_name, data) click to toggle source
# File lib/pusher-client/socket.rb, line 168
def send_event(event_name, data)
  payload = {'event' => event_name, 'data' => data}.to_json
  @connection.send(payload)
  PusherClient.logger.debug("Pusher : sending event : #{payload}")
end
subscribe(channel_name, user_id = nil) click to toggle source
# File lib/pusher-client/socket.rb, line 84
def subscribe(channel_name, user_id = nil)
  @user_data = {:user_id => user_id}.to_json unless user_id.nil?

  channel = @channels << channel_name
  if @connected
    authorize(channel, method(:authorize_callback))
  end
  return channel
end
subscribeAll()

For compatibility with JavaScript client API

Alias for: subscribe_all
subscribe_all() click to toggle source
# File lib/pusher-client/socket.rb, line 117
def subscribe_all
  @channels.channels.clone.each{ |k,v|
    subscribe(k)
  }
end
Also aliased as: subscribeAll
unsubscribe(channel_name) click to toggle source
# File lib/pusher-client/socket.rb, line 94
def unsubscribe(channel_name)
  channel = @channels.remove channel_name
  if @connected
    send_event('pusher:unsubscribe', {
      'channel' => channel_name
    })
  end
  return channel
end

Protected Instance Methods

parser(data) click to toggle source
# File lib/pusher-client/socket.rb, line 188
def parser(data)
  begin
    return JSON.parse(data)
  rescue => err
    PusherClient.logger.warn(err)
    PusherClient.logger.warn("Pusher : data attribute not valid JSON - you may wish to implement your own Pusher::Client.parser")
    return data
  end
end
send_local_event(event_name, event_data, channel_name) click to toggle source
# File lib/pusher-client/socket.rb, line 176
def send_local_event(event_name, event_data, channel_name)
  if (channel_name)
    channel = @channels[channel_name]
    if (channel)
      channel.dispatch_with_all(event_name, event_data)
    end
  end

  @global_channel.dispatch_with_all(event_name, event_data)
  PusherClient.logger.debug("Pusher : event received : channel: #{channel_name}; event: #{event_name}")
end