使用 MQTT 自建消息推送服务

593 阅读1分钟

在开发的过程中需要用到推送服务,笔者使用过各种xx平台的推送服务(免费版),然而不可避免会出现推送消息不稳定甚至丢失数据的情况,基于此在研究了mqtt协议之后决定自建推送服务,虽然会增加维护成本,但是由于不用依赖第三方服务从而减少和外部系统的交互从而提升性能。

Server端

下面推荐一款前华为Developer基于Erlang/OTP开发的Mqtt Broker: emqtt, 其服务开箱即用,支持百万级连接和分布式集群。

 sudo apt-get install erlang
 jane➜data/project/emqttd(master)» ls                                                                                                [21:52:47]
 bin      data     erts-8.3 etc      hook_lua lib      log      releases
  • 启动服务
 jane➜data/project/emqttd(master)» cd bin                                                                                             [21:52:47]
 jane➜project/emqttd/bin(master)» ls                                                                                                 [21:56:05]
 cuttlefish              emqttd                  emqttd_ctl              install_upgrade_escript start_clean.boot
 emqenv                  emqttd.cmd              emqttd_ctl.cmd          nodetool
 jane➜project/emqttd/bin(master)» ./emqttd start                                                                                     [21:56:05]
 emqttd 2.2 is started successfully!
  • emqtt提供了一个Web管理控制台:http://localhost:18083/ image.png
  • 笔者在生产环境中使用了该server,稳定运行3个多月(贴图为证) image.png

Client端

  • 以Ruby On Rails为例
  1. gem install mqtt
  2. vi config/mqtt.yml
 development:
   host: 127.0.0.1
   port: 1883
   username: admin
   password: public
 
 production:
   host: 127.0.0.1
   port: 1883
   username: xxx
   password: xxxx
  1. vi config/initializers/mqtt.rb
 require 'mqtt'
 # 读取配置
 conf = YAML.load_file("#{Rails.root}/config/mqtt.yml")[Rails.env]
 # 连接服务
 if conf
   $mqtt = MQTT::Client.connect(
     conf['host'], username: conf['username'], password: conf['password'],
     client_id: "test_#{Time.now.to_i+rand(9999)}"
   )
 end
 if $mqtt.present?
   # 开启线程 避免连接堵塞
   Thread.new do
   # 订阅所有topic
    $mqtt.get('#') do |topic, msg|
        Rails.logger.debug "topic: #{topic}, msg: #{msg}"
    end
   end
 end
  1. rails s
  2. 在另一个终端启动rails c
 [4] pry(main)> $mqtt.publish('test', 'hello mqtt')
 => nil
 [5] pry(main)>
  1. 查看rails日志
 jane➜data/service/Poly-ruby-server(release_reappoint)» rs -p 3004
 => Booting Puma
 => Rails 4.2.6 application starting in development on http://localhost:3004
 => Run `rails server -h` for more startup options
 => Ctrl-C to shutdown server
 Puma starting in single mode...
 * Version 3.9.1 (ruby 2.3.0-p0), codename: Private Caller
 * Min threads: 0, max threads: 16
 * Environment: development
 * Listening on tcp://localhost:3004
 Use Ctrl-C to stop
 topic: test, msg: hello mqtt