2011-03-10 74 views
0

我寫了一個web應用程序,它與/ dev/ttyS02上的串行設備進行交互。 問題是我目前的消息傳遞和排隊解決方案。請閱讀下面。如何創建pyserial網絡服務?

繼承人的應用和pyserial溝通的橋樑:

  • 我的web應用程序通過插入一個PHP請求記錄到MySQL中的d_requests表。 插入記錄的處理列設置爲0. 插入記錄的ID保存在$ id變量中,並且PHP應用程序輸入 循環狀態,在該狀態下,它將持續檢查d_requests [processed]列= 1是否使用 $ id作爲查找參考。

  • 我有一個python守護進程服務,每隔一秒檢查 d_requests表中處理的列= 0的記錄。 這被認爲是一個新的請求。 (參照源代碼 - 蟒服務)

  • 然後蟒服務使用該記錄的信息經由 pyserial連接到的端口。

  • 執行請求的操作。記錄的處理列然後更新爲1 並且其他一些字段也會更新。 這標誌着處理過的記錄。

  • 然後PHP控制塊退出循環(Point 1.),並將結果作爲json 返回給JS應用程序。向用戶展示它。

音符

  • 串行設備能夠處理1個請求每250毫秒的一些點。
  • python守護進程服務監視d_requests表,查找每1秒處理的 列= 0的記錄。
  • 我的web應用程序與python守護進程服務的唯一通信是MySQL
    DB,通過在d_requests表中插入請求記錄。
  • 我使用PHP塊代碼每秒鐘使用插入的ID查找請求,以檢查 如果處理的列已更新爲1。

我的顧慮

失敗

的單點當守護程序服務沒有運行串行要求不能發生

至尊資源使用

我預計約4-5的要求秒每秒串行設備。使用當前實現的 來處理消息,數據庫將超時工作,並且CPU使用率會很高,因爲PHP應用程序和python守護進程/服務將連接並執行對數據庫的查詢,並且處理請求會出現延遲。

結論: 有沒有更好的方法來改進我當前的消息傳遞和排隊解決方案? 我認爲一個pyserial web服務將在這種情況下工作,例如,串行端口。連接到網絡插座,例如。主機:< 7000>我可以通過PHP發送一個請求到它並等待Web服務的響應。不幸的是我不知道該怎麼做。

任何想法?

謝謝

的源代碼

蟒蛇服務

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) 
+0

你有沒有試過看node.js,它有一個非常快速的事件驅動循環系統,可以處理很多像這樣的東西。 – RobertPitt 2011-03-11 00:13:41

回答

1

有沒有改善我目前信和排隊的解決方案更好的辦法?

你打賭!他們被稱爲消息隊列,他們很棒。

我最喜歡的是Gearman,是由同一個團隊編寫的,這個團隊給我們帶來了memcached。它有PHPPython綁定。它實際上不像RPC服務那樣是一個消息隊列。無論如何,它會讓你從你的環境中調用方法,並在另一個環境中處理它們。

在這種情況下,您希望使用Python編寫您的串行接口代碼,並將它作爲Gearman函數的所有功能公開。它將作爲守護進程坐下。您的PHP代碼可以通過Gearman調用這些函數。

+0

感謝Charles的迴應。我會考慮Gearman。 @RobertPitt不確定node.js是否可以用於我的目的,因爲我仍然需要與python(pyserial)&php進行通信。 – QCar 2011-03-11 06:52:03

0

研究類似的需求。發現到目前爲止有幫助的「ser2net」和「termnetd」守護進程。