如何在 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
我会在评论中写下这个,但它有点长......但我想知道你是否可以澄清你的问题,我会随时更新我的答案:
- 考虑到 Rails 能够 "autoload",为什么不在初始化文件中或在设置环境时初始化连接?
即,在 you_app/config/initializers
中名为 serial_port.rb
的文件中:
SERIAL_PORT_CONNECTION = Serialport::Connection.new
在您的 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
我想收听 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
我会在评论中写下这个,但它有点长......但我想知道你是否可以澄清你的问题,我会随时更新我的答案:
- 考虑到 Rails 能够 "autoload",为什么不在初始化文件中或在设置环境时初始化连接?
即,在 you_app/config/initializers
中名为 serial_port.rb
的文件中:
SERIAL_PORT_CONNECTION = Serialport::Connection.new
在您的 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