我编写了一个web应用程序,它与/dev/ttyS02 02上的串行设备进行交互。问题是我当前的消息传递和队列解决方案。请阅读下面的内容。
下面是应用程序和pyserial之间的通信桥:
注意事项的几点
My Concerns
单点故障
当守护进程服务没有运行时,不能发生串行请求。
极限资源使用
我预计每秒对串行设备的请求大约为4-5次。使用当前处理消息的实现,db将超时工作,CPU使用率将很高,因为PHP应用程序和python守护进程/服务将连接并执行DB上的查询,并且请求的处理将出现延迟。
结论:是否有更好的方法来改进我目前的消息传递和排队解决方案?我认为在这种情况下,一个pyserial服务会工作得很好,在这里,串口可以用于例如。连接到网络插座上。host:<7000>和我可以通过PHP向它发送一个请求,然后等待来自web服务的响应。不幸的是,我不知道该怎么做。
有什么想法吗?
谢谢
源代码
python服务
import sys, time
from daemon import Daemon
import MySQLdb
#Database parameters
config = {"host":"localhost","username":"root","password":"cake","database":"mydb"}
#Check if MySQLdb library is present
try:
conn = MySQLdb.connect(config['host'],config['username'],config['password'],config['database'])
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[o], e.args[1])
sys.exit(1);
#Check if pyserial library is present
try:
import serial
except ImportError:
print "Error,pySerial module not installed"
sys.exit(1);
#Create DB cursor
#cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
#Declare global variables here
class MyDaemon(Daemon):
def run(self):
while True:
time.sleep(2)
cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
data = ''
try:
cursor.execute ("""SELECT * FROM d_requests where processed = 0""")
rows=cursor.fetchall()
print "Waiting for requests..."
except MySQLdb.Error as detail:
print "MySQL Error,",detail
if len(rows) == 0:
cursor.close()
print "No request found..."
continue
for row in rows:
try:
print "Processing request..."
ser = serial.Serial(port=row['port'],
baudrate = row['baud'],
bytesize = row['bytesize'], #8
parity = row['parity'], #serial.PARITY_NONE or N or C
stopbits = row['stopbits'], #1
timeout = row['wait_for_reply'], #0.5
xonxoff = row['sw_flowcontrol'], #0
rtscts = row['hw_flowcontrol']) #0
#Send command to device
ser.write(row['request_string'] + "\r")
#Read device response
data = ser.read(100)#TBD:This value needs to be changeable,not always 100 bytes
ser.close()
print "RESULT : " + data
except (serial.SerialException, AttributeError, NameError) as detail:
data = "Error, could not open port"
print data
except serial.SerialTimeoutException as detail:
data = "Error, port connection timeout" #Error ,detail
print data
except:
data = "Error,Unexpected error"
print data
finally:
#ser.close()
try:
cursor.execute("""UPDATE d_requests SET processed = %s, result_string = %s WHERE id = %s""",(1,data,row['id']))
except MySQLdb.Error as detail:
print "MySQL Error,",detail
#cursor.commit() for innoDB table engines
cursor.close()
if __name__ == "__main__":
daemon = MyDaemon('/tmp/daemon-example.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
elif 'foreground' == sys.argv[1]: #this runs the daemon in the foreground
daemon.run()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)发布于 2011-03-11 00:11:31
是否有更好的方法来改进我当前的消息传递和队列解决方案?
行!没问题!它们被称为消息队列,它们是非常棒的。
我最喜欢的是吉尔曼,它是由给我们带来memcached的同一个团队编写的。它有PHP和Python绑定。它实际上不是消息队列,而是RPC服务。无论如何,它将允许您从一个环境调用方法,并在另一个环境中处理它们。
在本例中,您希望用Python编写串行接口代码,并让它公开它作为Gearman函数可以做的所有事情。它将作为守护进程打开。PHP代码可以通过Gearman调用这些函数。
发布于 2011-08-25 17:35:50
研究类似的需求。到目前为止,"ser2net“和"termnetd”守护进程都很有帮助。
https://stackoverflow.com/questions/5266347
复制相似问题