2011-07-29 26 views
13

Tôi muốn chuyển kết nối cơ sở dữ liệu của mình đến lớp EchoHandler, tuy nhiên tôi không thể tìm ra cách thực hiện hoặc truy cập lớp EchoHandler .Với socketserver python làm thế nào tôi có thể truyền một biến cho hàm tạo của lớp xử lý

 

class EchoHandler(SocketServer.StreamRequestHandler): 
    def handle(self): 
     print self.client_address, 'connected' 

if __name__ == '__main__': 
    conn = MySQLdb.connect (host = "10.0.0.5", user = "user", passwd = "pass", db = "database") 

    SocketServer.ForkingTCPServer.allow_reuse_address = 1 

    server = SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler) 

    print "Server listening on localhost:4242..." 
    try: 
     server.allow_reuse_address 
     server.serve_forever() 
    except KeyboardInterrupt: 
     print "\nbailing..." 

Trả lời

23

Thật không may, thực sự không phải là cách dễ dàng để truy cập trình xử lý trực tiếp từ bên ngoài máy chủ.

Bạn có hai lựa chọn để có được những thông tin cho các trường hợp EchoHandler:

  1. Store kết nối như một thuộc tính của máy chủ (thêm server.conn = conn trước khi gọi server_forever()) và sau đó truy cập mà tài sản trong EchoHandler.handler qua self.server.conn .
  2. Bạn có thể ghi đè lên máy chủ finish_request và gán giá trị ở đó (bạn sẽ phải chuyển nó tới hàm tạo của EchoHandler và ghi đè EchoHandler .__ init__). Đó là một giải pháp xa messier và rất nhiều yêu cầu bạn phải lưu trữ kết nối trên máy chủ.

optionon của tôi đặt cược tốt nhất của bạn:

class EchoHandler(SocketServer.StreamRequestHandler): 
    def handle(self): 
     # I have no idea why you would print this but this is an example 
     print(self.server.conn); 
     print self.client_address, 'connected' 

if __name__ == '__main__': 
    SocketServer.ForkingTCPServer.allow_reuse_address = 1 

    server = SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler) 
    server.conn = MySQLdb.connect (host = "10.0.0.5", 
        user = "user", passwd = "pass", db = "database") 
    # continue as normal 
+0

Đó là công trình đẹp, Cảm ơn bạn! – Jesse

9

Mark T có sau đây để nói về danh sách python lưu trữ

Trong lớp handler, self.server đề cập đến đối tượng máy chủ, để phân lớp máy chủ và ghi đè init để lấy bất kỳ thông số máy chủ bổ sung nào và lưu trữ chúng dưới dạng biến mẫu.


import SocketServer 

class MyServer(SocketServer.ThreadingTCPServer): 

    def __init__(self, server_address, RequestHandlerClass, arg1, arg2): 
     SocketServer.ThreadingTCPServer.__init__(self, 
               server_address, 
               RequestHandlerClass) 
     self.arg1 = arg1 
     self.arg2 = arg2 


class MyHandler(SocketServer.StreamRequestHandler): 

    def handle(self): 
     print self.server.arg1 
     print self.server.arg2 

+0

Tại sao không thực hiện 'super() .__ init __ (...)' thay cho 'MyServer .__ init__'? –

+1

Các lớp trong mô-đun SocketServer là các lớp "kiểu cũ". Nhà xây dựng siêu phải được gọi theo cách này. Xem tại đây: https://stackoverflow.com/questions/11527921/python-inheriting-from-old-style-classes – aramaki

0

Một cách khác, mà tôi tin pythonic hơn, là phải làm như sau:

class EchoHandler(SocketServer.StreamRequestHandler): 
    def __init__(self, a, b): 
    self.a = a 
    self.b = b 

    def __call__(self, request, client_address, server): 
    h = EchoHandler(self.a, self.b) 
    SocketServer.StreamRequestHandler.__init__(h, request, client_address, server) 

Bây giờ bạn có thể đưa ra một dụ của handler của bạn vào TCPServer:

SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler("aaa", "bbb")) 

TCPServer thường tạo một phiên bản mới của EchoHandler theo yêu cầu nhưng trong trường hợp này, __call__ phương pháp sẽ được gọi thay vì các nhà xây dựng (nó đã là một ví dụ.)

Trong gọi phương pháp, tôi dứt khoát tạo một bản sao của EchoHandler hiện tại và vượt qua nó để các nhà xây dựng siêu để phù hợp với các logic ban đầu của "một trình xử lý cho mỗi yêu cầu".

Điều đáng có một cái nhìn tại các mô-đun SocketServer để hiểu những gì xảy ra ở đây: https://github.com/python/cpython/blob/2.7/Lib/SocketServer.py

Các vấn đề liên quan