I have a trying to send SMS messages with ruby-smpp. Following the project examples and some research into em-redis and eventmachine, I have the following gateway.rb configuration:
loop do
EventMachine::run do
@@tx = EventMachine::connect(
config[:host],
config[:port],
Smpp::Transceiver,
config,
self # delegate that will receive callbacks on MOs and DRs and other events
)
MessageSender.next # gets the messages from redis list and sends at each click of the EventMachine
end
puts "Disconnected. Reconnecting in 5 seconds.."
sleep 5
end
MessageSender is this module:
module MessageSender
def self.redis
@redis ||= EM::Hiredis.connect
end
def self.next
redis.blpop("company-out", 0) do |item|
if item[1]
message_hashed = JSON.parse(item[1])
CompanyGateway.send_mt(message_hashed["from"],
message_hashed["to"],
message_hashed["message"])
end
EM.next_tick(&method(:next))
end
end
end
What works: I start the gateway and connect to SMSC simulator. I add messages to redis list and it gets sent fine.
What breaks: There are already values in the redis list, and running gateway.rb breaks with following error:
Exception in SMS Gateway: Transceiver is unbound. Cannot send MT messages. at /vagrant/lib/ruby-smpp/lib/smpp/transceiver.rb:28:in `send_mt'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:87:in `send_mt'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:66:in `block in next'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/client.rb:149:in `block in method_missing'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/eventmachine-0.12.10/lib/em/deferrable.rb:134:in `call'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/eventmachine-0.12.10/lib/em/deferrable.rb:134:in `set_deferred_status'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/eventmachine-0.12.10/lib/em/deferrable.rb:173:in `succeed'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/client.rb:75:in `block in connect'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `call'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `block in emit'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `each'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/event_emitter.rb:8:in `emit'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/em-hiredis-0.1.0/lib/em-hiredis/connection.rb:21:in `receive_data'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine'
/home/vagrant/.rvm/gems/ruby-1.9.2-p290/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:103:in `block in start'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:102:in `loop'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:102:in `start'
/vagrant/lib/ruby-smpp/gateways/ucellgate.rb:186:in `<main>'
I would like to be able to run the gateway regardless of redis list is empty or not, and send both the stored messages and the ones that arrive in the list in the future. Any advice?
This doesn’t look like a redis issue. The exception is coming from CompanyGateway.send_mt. My guess would be, when you startup with items on the redis queue, you try to send messages before the connection has completed.
You could try wrapping the initial MessageSender.next call in an EM.add_timer(5) { MessageSender.next } to delay the initial call a few seconds to allow the connection to complete.