2009-05-07 2 views
0

서버에서 연결된 클라이언트로 데이터를 전송해야하는 웹 응용 프로그램을 작성하고 있습니다. 이 데이터는 웹 응용 프로그램의 다른 스크립트에서 보낼 수 있습니다. 예를 들어 한 사용자가 서버를 변경하면 다른 사용자에게이를 알립니다.연결된 사용자와 유닉스 소켓간에 프록시로 TCP 서버 스레딩

내 생각에 유닉스 소켓 (사용자 #ID를 기반으로하는 소켓으로의 경로)을 사용하여 해당 사용자의 데이터를 전송합니다 (웹 응용 프로그램 스크립트는이 소켓에 연결하여 데이터를 작성합니다). 두 번째 부분은 사용자 연결을 허용하고 TCP 소켓 연결을 통해 유닉스 소켓에서 사용자로 데이터를 전송하는 ThreadingTCPServer입니다. 중고

  1. 는 TCP 서버
  2. 장고 스크립트 개방 unixsocket에 연결하여 데이터를 기록 : 여기

    워크 플로입니다.
  3. TCP 서버가 유닉스 소켓에서 데이터를 읽어서 사용자와의 연결을 열어 보냅니다. 당신은 일반적으로 내 생각에 대해 생각

    1.What : 나는 희망

당신은 그래서, 나는이 개 질문이 내 생각 :

을 이해? 그것은 좋은 해결책인가 나쁜가? 모든 추천을 환영합니다.

2. 여기 내 코드입니다.

import SocketServer 
import socket 
import netstring 
import sys, os, os.path 
import string 
import time 

class MyRequestHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     try: 
      print "Connected:", self.client_address 

      user = self.request.recv(1024).strip().split(":")[1] 
      user = int(user) 
      self.request.send('Welcome #%s' % user) 

      self.usocket_path = '/tmp/u%s.sock' % user 
      if os.path.exists(self.usocket_path): 
       os.remove(self.usocket_path) 

      self.usocket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) 
      self.usocket.bind(self.usocket_path) 
      self.usocket.listen(1) 

      while 1: 
       usocket_conn, addr = self.usocket.accept() 
       while 1: 
        data = usocket_conn.recv(1024) 
        if not data: break 
        self.request.send(data) 
        break 
       usocket_conn.close() 
       time.sleep(0.1) 

     except KeyboardInterrupt: 
      self.request.send('close') 
      self.request.close() 

myServer = SocketServer.ThreadingTCPServer(('', 8081), MyRequestHandler) 
myServer.serve_forever() 

나는 예외이 너무 복잡

File "server1.py", line 23, in handle 
    self.usocket.listen(1) 
    File "<string>", line 1, in listen 
error: (102, 'Operation not supported on socket') 
+0

두 번째 질문이 해결되었습니다. UNIX 소켓에서는 socket.SOCK_DGRAM 대신 socket.SOCK_STREAM을 사용해야합니다. –

답변

1

유닉스 소켓을 사용하면 안된다고 생각합니다. 앱이 (언젠가) 대중화되거나 미션 크리티컬하게되면 확장 성을 추가하거나 중복되거나 오류가없는 서버를 추가 할 수 없습니다.

반면에 데이터를 f.e. memcached (및 사용자의 "데이터 세트 번호"를 별도의 키로 사용) 여러 서버의 memcached에 데이터를 넣고 여러 서버에서 읽을 수 있습니다. 사용자가 연결을 끊고 다른 서버에서 다시 연결하면 계속해서 해당 데이터를 가져올 수 있습니다.

당신은 데이터베이스를 사용할 수도 있습니다 (더 안전한 시스템을 만들기 위해). 또는 데이터베이스와 memcached를 원하는대로 조합 할 수 있습니다. 그러나 유닉스 소켓을 사용하는 응용 프로그램을 보려고 시도하고 있습니다. 프로그래머는 나중에 그것을 후회했다. 테이블에는 사용자 ID, 데이터 및 타임 스탬프 열이있을 수 있으며 주어진 사용자의 마지막 타임 스탬프를 기억할 수 있습니다.

+0

동시에 최대 사용자 수는 1000 명입니다. 나는 하나의 서버가 1000 개의 연결을 처리하는 것이 그렇게 중요하지 않다고 생각한다. 물론 데이터베이스가 사용됩니다. memcached 솔루션을 주셔서 감사합니다, 나는 그것에 대해 생각할 것입니다.하지만 예를 들어 매초마다 확인하는 대신 새 데이터를 "청취"할 수 있는지 확실하지 않습니다. –

+0

정말 데이터가 즉시 필요합니까? 대부분의 경우, 당신은하지 않습니다. 나는 인정한다, 때때로 너는 그렇지만 사람들만큼 자주 생각하지는 않는다. BTW : ulimit를 높이면 1000 개 이상의 열린 소켓을 얻을 수 있습니다. –

0

을 얻었다. socketserver 모듈을 사용하십시오.

+0

myServer = SocketServer.ThreadingTCPServer (('' ', 8081), MyRequestHandler) 아니야? –

+0

그게 http://docs.python.org/library/socketserver입니다.html # asynchronous-mixins says –

0

데이터를 클라이언트에 푸시하려면 Twisted 또는 더 구체적으로 Orbited을 사용해야합니다. 게시 한 샘플 코드에는 여러 가지 잠재적 인 문제가 있으며 필요로하는 것을 수행하기 위해 미리 작성된 코드 조각을 사용하는 것보다 모두 무엇인지 파악하는 것이 훨씬 더 어려울 것입니다.