如何在 Rails 上的 Ruby 中创建并保持串行端口连接,处理无限循环以使用新消息创建模型?

How to create and keep serialport connection in Ruby on Rails, handle infinity loop to create model with new messages?

我想收听 SerialPort,当消息出现时,获取或创建 Log 具有从我的设备接收到的 ID 的模型。

如何自动加载一次 SerialPort 并保持已建立的连接,如果 key_detected? in listener 处理 Log 模型?

这是我在 lib:

中自动加载的模块
module Serialport
  class Connection
    def initialize(port = "/dev/tty0")
      port_str = port
      baud_rate = 9600
      data_bits = 8
      stop_bits = 1
      parity = SerialPort::NONE
      @sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)
      @key_parts = []
      @key_limit = 16 # number of slots in the RFID card.
      while true do
        listener
      end
      @sp.close
    end

    def key_detected?
      @key_parts << @sp.getc
      if @key_parts.size >= @key_limit
        self.key = @key_parts.join()
        @key_parts = []
        true
      else
        false
      end
    end

    def listener
      if key_detected?
        puts self.key
        # log = Log.find(rfid: self.key).first_or_create(rfid: self.key)
      end
    end
  end
end

型号:

class Log < ActiveRecord::Base
end

我会在评论中写下这个,但它有点长......但我想知道你是否可以澄清你的问题,我会随时更新我的​​答案:

  1. 考虑到 Rails 能够 "autoload",为什么不在初始化文件中或在设置环境时初始化连接?

即,在 you_app/config/initializers 中名为 serial_port.rb 的文件中:

SERIAL_PORT_CONNECTION = Serialport::Connection.new
  1. 在您的 Rails 应用程序中实施无限循环很可能会挂起 Rails 应用程序并阻止其用作网络服务。

    你想要完成什么?

    如果您只想使用 active_record 或 active_support,为什么不将这两个 gem 包含在单独的脚本中呢?

    或者,考虑为无限循环创建一个单独的线程(或者更好的是,使用反应器(它们并不难写,但是有很多预先写好的,例如Iodine 我为实现 Web 服务而写的)...

这是一个更新后的侦听器方法的示例,使用单独的线程,因此您只需调用它一次:

def listener
   Thread.new do
     loop { self.key while key_detected? }
     # this will never be called - same as in your code.
     @sp.close
   end
end