Redmine中消息主动推送的实现方法

该方法能够实现在创建问题以及更改任务承担人时主动推送消息,不过需要借助相关消息总线,我这里使用的是rabbitmq;

一、创建一个 RabbitMQ 生产者。我们称之为发布者。我们将使用 bunny 这个超易用的 RabbitMQ Ruby 客户端。

1、在Gemfile中添加如下行,文件路径为:/opt/redmine/redmine-2.6.7/Gemfile 
gem "bunny"
2、运行如下命令完成插件安装:
bundle install
或者
apt-get install ruby-bunny                                                                 

3、新建文件:app/models/publisher.rb
  
  
class Publisher
  # In order to publish message we need a exchange name.
  # Note that RabbitMQ does not care about the payload -
  # we will be using JSON-encoded strings
  def self.publish( message = {})
    # grab the fanout exchange
    x = channel.fanout("task")
    # and simply publish message
    x.publish(message.to_json)
  end

  def self.channel
    @channel ||= connection.create_channel
  end

  # We are using default settings here
  # The `Bunny.new(...)` is a place to
  # put any specific RabbitMQ settings
  # like host or port
  def self.connection
    @connection ||= Bunny.new('amqp://admin: admin@192.168.1.101:5672/todo').tap do |c|
      c.start
    end
  end
end
4、调整系统创建问题时调用 Publisher.publish,修改app/controllers/issues_controller.rb文件:
1、在 create方法下添加行:
if @issue.save
       #########ADD#########
       if @issue.assigned_to_id
            send_message("192.168.1.100", "create")
         end
       #########END#########
       call_hook(:controller_issues_new_after_save, { :params => params, :issue  => @issue})
        ......
2、在update方法下添加如下行:
def update
    ##########ADD##########
    orign = @issue.assigned_to_id
    ##########END##########
    return unless update_issue_from_params
    ......
    if saved
        ##########ADD##########
        now = @issue.assigned_to_id
        if (now and (orign != now))
            send_message("192.168.1.100", "update")
        end
        ##########END##########
        render_attachment_warning_if_needed(@issue)
        ......
3、在文档中定义相应函数:
    def send_message(ip, action)
        @issue["host"] = ip
        @issue["action"] = action
        @issue["login_name"] = User.find_by_id(@issue.assigned_to_id)['login']
        @issue["project_name"] = Project.find(@issue.project_id)['name']
        Publisher.publish(@issue)
    end

二、我们需责成 blog.posts 交换将收到的消息发送给dashboard.posts 队列。尽管这个操作可以在 RabbitMQ 管理页面完成,但是我们最好将此操作做成可被自动执行
(比如,部署时自动执行)的配置文件的形式。我们还是使用 bunny 库。

1、新建 /opt/redmine/redmine-2.6.7/Rakefile 文件:
# Rakefile
namespace :rabbitmq do
  desc "Setup routing"
  task :setup do
    require "bunny"

    conn = Bunny.new('amqp://admin:admin@192.168.1.101:5672/task')
    conn.start

    ch = conn.create_channel

    # get or create exchange
    x = ch.fanout("task")

    # get or create queue (note the durable setting)
    queue = ch.queue("task_queue", durable: true)

    # bind queue to exchange
    queue.bind("task")

    conn.close
  end
end
2、运行:
rake rabbitmq:setup
3、修改 /etc/rc.local 文件,添加如下行,让命令开机自启动:
  
  
/usr/local/bin/rake rabbitmq:setup -f /opt/redmine/redmine-2.6.7/Rakefile
三、接收测试代码:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import pika

parameters = pika.URLParameters('amqp://admin:admin@192.168.1.101:5672/task')
connection = pika.BlockingConnection(parameters)
channel = connection.channel()

#定义交换机
channel.exchange_declare(exchange='task', type='fanout')

#定义队列
channel.queue_declare(queue='task_queue', durable=True)
print ' [*] Waiting for n'

#绑定队列
channel.queue_bind(exchange='task', queue='task_queue')

def callback(ch, method, properties, body):
        print '----->', body
        ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback, queue='task_queuee', no_ack=False)

print ' [*] Waiting for messages. To exit press CTRL+C'
try:
        channel.start_consuming()
except KeyboardInterrupt:
        channel.stop_consuming()
        connection.close()

  
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值