Skip to content

Commit

Permalink
ability to connect to private channels
Browse files Browse the repository at this point in the history
  • Loading branch information
genaromadrid committed Apr 25, 2018
1 parent 8b80f90 commit 73a2f9a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 13 deletions.
57 changes: 57 additions & 0 deletions examples/private.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

require './lib/em/pusher/client'

pusher_key = 'pusher_key'
channel = 'private-channel'
pusher_secret = 'pusher_secret'

EM.run do
opts = {
key: pusher_key,
cluster: 'us2',
port: 80,
scheme: 'ws',
}
EM::Pusher::Client.connect(opts) do |conn|
conn.connected do
puts 'connected'
end

conn.connection_established do |socket_id|
puts 'callback'
auth = EM::Pusher::Client.build_auth(pusher_secret, pusher_key, socket_id, channel)
msg = {
event: 'pusher:subscribe',
data: {
channel: channel,
auth: auth,
},
}
conn.send_msg(msg)
end

conn.errback do |e|
puts "Got error: #{e}"
end

conn.stream do |msg|
case msg.event
when 'pusher:connection_established'
puts 'Connection Established'
when 'pusher_internal:subscription_succeeded'
puts "Subscribed to #{msg.json['channel']}"
when 'someevent'
puts "#{msg.type}: #{msg.event} >> #{msg.data}"
else
puts "unexpected event (#{msg.type}): <#{msg}>"
end
# conn.close_connection if closed?
end

conn.disconnect do
puts 'gone'
EM.stop_event_loop
end
end
end
11 changes: 11 additions & 0 deletions lib/em/pusher/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ def self.connect(options)
end
end

def self.sign(secret, socket_id, channel_name)
digest = OpenSSL::Digest::SHA256.new
string_to_sign = "#{socket_id}:#{channel_name}"
OpenSSL::HMAC.hexdigest(digest, secret, string_to_sign)
end

def self.build_auth(secret, key, socket_id, channel_name)
sig = sign(secret, socket_id, channel_name)
"#{key}:#{sig}"
end

def self.url(options)
opts = DEFAULT_OPTIONS.merge(options)
REQUIRED_OPTIONS.each { |opt| fail ArgumentError, "option #{opt} is required" unless opts[opt] }
Expand Down
37 changes: 36 additions & 1 deletion lib/em/pusher/client/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'uri'
require 'json'
require 'websocket'
require 'openssl'

module EM
module Pusher
Expand Down Expand Up @@ -53,6 +54,14 @@ def disconnect(&cback)
@disconnect = cback
end

def connection_established(&cback)
@connection_established = cback
end

def ping(&cback)
@ping = cback
end

# https://pusher.com/docs/pusher_protocol#subscription-events
def subscribe(channel, auth = nil, channel_data = nil)
msg = {
Expand Down Expand Up @@ -98,8 +107,34 @@ def unbind
def handle_received_data(data)
@frame << data
while (msg = @frame.next)
@stream.call(EM::Pusher::Client::MsgParser.new(msg)) if @stream
process_data(EM::Pusher::Client::MsgParser.new(msg))
end
end

def process_data(parser)
if parser.event == 'pusher:connection_established'
process_connection(parser)
elsif parser.type == :ping
process_ping
elsif parser.type == :close
process_close
end
@stream.call(parser) if @stream
end

def process_connection(parser)
socket_id = JSON.parse(parser.json['data'])['socket_id']
@connection_established.yield(socket_id) if @connection_established
end

def process_ping
@ping.yield if @ping
send_msg(event: 'pusher:pong')
end

def process_close
unbind
close_connection
end
end
end
Expand Down
25 changes: 14 additions & 11 deletions lib/em/pusher/client/msg_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,38 @@ module EM
module Pusher
module Client
class MsgParser
attr_reader :json,
:data

def initialize(msg)
parse(msg)
@msg = msg
end

def event
return '{}' unless json
@event ||= json['event']
end

def to_s
@msg.to_s
end

private
def type
@msg.type
end

def json
@json ||= JSON.parse(@msg.data)
rescue JSON::ParserError
{}
end

def parse(msg)
@msg = msg
@json = JSON.parse(msg.data)
def data
@data =
if json['data'].is_a?(String)
JSON.parse(json['data'])
else
json['data']
end
rescue JSON::ParserError => e
puts "Error parsing event '#{event}': '#{e.message}'"
# logger.error("Error parsing msg #{e}")
rescue JSON::ParserError
{}
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/em/pusher/client/msg_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def build_msg(msg)
let!(:parser) { described_class.new(build_msg(malformed)) }

it { expect(parser.event).to eq('pusher:someevent') }
it { expect(parser.data).to be_nil }
it { expect(parser.data).to eq({}) }
it { expect(parser.to_s).to eq(malformed) }
end
end
Expand Down

0 comments on commit 73a2f9a

Please sign in to comment.