2011-03-10 5 views
0

나는/dev/ttyS02의 시리얼 장치와 상호 작용하는 웹 어플리케이션을 작성했다. 문제는 현재의 메시징 및 대기열 솔루션입니다. 아래 내용을 읽어주십시오.pyserial 웹 서비스를 만들려면 어떻게해야합니까?

Heres는 응용 프로그램과 pyserial 간의 통신 다리 :

  • 내 웹 응용 프로그램의 MySQL의 d_requests 테이블에 PHP를 통해 요청 기록을 삽입합니다. 삽입 된 레코드의 처리 된 열이 0으로 설정됩니다. 삽입 된 레코드의 ID가 $ id 변수에 저장되고 PHP 응용 프로그램이 루프 상태로 들어가면 d_requests [processed] 열이 1이면 $ ID를 조회 참조로 사용합니다.

  • 난 가공 열에 = 0 이 새로운 요청으로 간주된다 d_requests 테이블에서 레코드 매초 확인 파이썬 데몬 서비스가있다.

  • 파이썬 서비스는 다음 pyserial를 통해 포트에 연결 할 레코드의 정보를 사용하여 - 은 (파이썬 서비스 소스 코드 참조).

  • 요청한 작업이 수행됩니다. 그러면 레코드의 처리 된 열이 1 으로 업데이트되고 몇 개의 다른 필드도 업데이트됩니다. 레코드가 처리 된 것으로 표시합니다.

  • PHP 컨트롤 블록은 루프 (포인트 1)를 빠져 나와 결과를 json 으로 JS 애플리케이션에 반환합니다. 사용자에게 표시됩니다. 참고

    • 직렬 장치마다 250 밀리 1 개 요청 처리 능력의

    일부 포인트.

  • 파이썬 데몬 서비스는 d_requests 테이블에서 처리 된 열이 0 인 레코드를 1 초마다 모니터링합니다.
  • 내 웹 응용 프로그램과 python 데몬 서비스 간의 유일한 통신은 d_requests 테이블에 요청 레코드를 삽입하여 MySQL
    DB입니다.
  • PHP 블록 코드를 사용하여 매초마다 삽입 된 ID를 사용하여 요청을 조회하여 처리 된 열이 1로 업데이트 된 경우 을 확인합니다.

내 우려

실패

단일 포인트 데몬 서비스는

익스트림 리소스 사용을 놓고

나는 참을 수 없어 시리얼 요청을 실행하지 않은 경우 약 4-5 요청을 기대하다. 초당 직렬 장치 수입니다. PHP 응용 프로그램과 Python 데몬/서비스가 연결되어 DB에 대한 쿼리를 수행하고 요청 처리가 지연 될 것이므로 메시지 처리에 현재 구현 을 사용하면 db가 초과 작업하고 CPU 사용률이 높습니다.

결론 : 내 메시징 및 대기열 솔루션을 개선하는 더 좋은 방법이 있습니까? pyserial 웹 서비스가이 경우에 훌륭하게 작동 할 것이라고 생각합니다. 예를 들어 직렬 포트가있는 곳입니다. 예 : 웹 소켓에 부착되어 있습니다. host : < 7000> 그리고 PHP를 통해 요청을 보내고 응답을 웹 서비스에서 다시 기다릴 수 있습니다. 불행히도 나는 이것을 어떻게하는지 모른다.

아이디어가 있으십니까?

소스 코드

파이썬 서비스

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

답변

1

내 현재 메시징 및 대기 솔루션을 개선하기 위해 더 나은 방법이 있나요 감사합니다?

내기! 그것들은 메시지 대기열 (message queue)이라고 불리며, 그들은 굉장합니다.

내 마음에 드는 사람은 Gearman이며 memcached를 가져온 팀과 똑같습니다. 그것에는 PHPPython 바인딩이있다. 실제로 RPC 서비스만큼 메시지 대기열이 아닙니다. 그럼에도 불구하고, 그것은 여러분이 여러분의 환경 중 하나로부터 메소드를 호출하고 다른 환경에서 메소드를 처리하게합니다.

이 경우, 직렬 인터페이스 코드를 파이썬으로 작성하고 Gearman 기능으로 수행 할 수있는 모든 작업을 공개해야합니다. 데몬으로 열리게됩니다. PHP 코드는 Gearman을 통해 이러한 함수를 호출 할 수 있습니다.

+0

답장을 보내 주신 Charles 께 감사드립니다. 나는 기어 맨을 조사 할 것이다. @RobertPitt 내가 파이썬 (pyserial) 및 PHP와 통신 할 필요가 있기 때문에 node.js가 제 목적으로 작동하는지 확실하지 않습니다. – QCar

0

비슷한 필요성을 연구 중이다. 지금까지 유용한 "ser2net"및 "termnetd"데몬을 발견했습니다.

관련 문제