2013-10-03 9 views
10

Tôi đang sử dụng Mô-đun Máy ứng dụng trong dự án python của mình. (https://developers.google.com/appengine/docs/python/modules/#Python_Background_threads)Mô-đun Python của Máy ứng dụng và dịch vụ kênh

Tôi cũng đang sử dụng các kênh truyền hình trong m dự án: https://developers.google.com/appengine/docs/python/channel/

Tôi muốn trực tiếp các thông điệp bài/ngắt kết nối kết nối ('/ _ah/kênh/kết nối /', '/ _ah/kênh/ngắt kết nối/') vào mô-đun api của tôi. Ngay bây giờ tôi không thể nhận được chúng để hiển thị trong bất kỳ mô-đun (mặc định hoặc api)

app.yaml

api_version: 1 
    application: integrate 
    version: 1-0-0 
    runtime: python27 
    threadsafe: true 

    builtins: 
     - deferred: on 

    libraries: 
     - name: pycrypto 
     version: "2.6" 

    handlers: 
     - url: /favicon\.ico 
     static_files: static/favicon.ico 
     upload: static/favicon\.ico 

     - url: /admin/.+ 
     script: src.default.main.app 
     login: admin 

     - url: /.* 
     script: src.default.main.app 

api.yaml

api_version: 1 
    application: integrate 
    module: api 
    version: 1-0-0 
    runtime: python27 
    threadsafe: true 

    inbound_services: 
     - channel_presence 

    builtins: 
     - deferred: on 

    libraries: 
     - name: pycrypto 
     version: "2.6" 

    handlers: 
     - url: /admin/.+ 
     script: src.api.main.app 
     login: admin 

     - url: /.* 
     script: src.api.main.app 

dispatch.yaml

application: integrate 

    dispatch: 
     - url: "*/_ah/channel/*" 
     module: api 

Lưu ý: Chỉ cần làm rõ điều này tất cả hoạt động trong chế độ dev cục bộ.

api.main.app

app = webapp2.WSGIApplication(debug=True) 
    _routes = [ 
     : 
     ChannelDisconnectedHandler.mapping(), 
     ChannelConnectHandler.mapping() 
    ] 

    for r in self._routes: 
     app.router.add(r) 

ChannelDisconnectHandler

CHANNEL_DISCONNECTED_URL_PATTERN = '/_ah/channel/disconnected/' 


    class ChannelDisconnectedHandler(RequestHandler): 

     @classmethod 
     def mapping(cls): 
      return CHANNEL_DISCONNECTED_URL_PATTERN, cls 

     def post(self): 
      """ 
      Channel Presence handler. Will be called when a client disconnects. 
      """ 
      channel_id = self.request.get('from') 
      logging.info("Channel Disconnect. Id: %s" % channel_id) 

ChannelConnectHandler

CHANNEL_CONNECT_URL_PATTERN = '/_ah/channel/connected/' 

    class ChannelConnectHandler(RequestHandler): 

     @classmethod 
     def mapping(cls): 
      return CHANNEL_CONNECT_URL_PATTERN, cls 

     def post(self): 
      """ 
      Channel Presence handler. Will be called when a client connects. 
      """ 
      channel_id = self.request.get('from') 
      logging.info("Channel Connect. Id: %s" % channel_id) 

Vì vậy, khách hàng của tôi (viết bằng javascript) bài viết để mô-đun api của tôi và mở ra một kênh.

var open_channel = function(tokenResponse) { 
     console.log("Open Channel. token Response: " + tokenResponse) 
     token = tokenResponse.token; 
     var channel = new goog.appengine.Channel(token); 
     if (socket != null) { 
      socket.close(); 
     } 
     socket = channel.open(); 
     socket.onopen = onOpened; 
     socket.onmessage = onMessage; 
     socket.onerror = onError; 
     socket.onclose = onClose; 
    }; 

    onOpened = function() { 
     console.info("Channel API Connection is open."); 
    }; 

    onError = function(e) { 
     console.info("CHANNEL Error. Code: " + e.code + ", Description: " + e.description); 
    }; 

    onClose = function() { 
     console.info("Close Channel"); 
    }; 

    onMessage = function(msg) { 
     console.info("Message Received: " + msg + ", Data: " + msg.data); 
    }; 

Chức năng gọi lại này đạt được với mã thông báo hợp lệ. Tôi tạo socket thành công và hoàn thành chức năng này như mong đợi. Trên hệ thống cục bộ của tôi, hàm onOpened sau đó được gọi và tôi nhận được các tin nhắn từ máy chủ. Trong sản xuất onOpened không bao giờ được gọi và tôi không bao giờ nhận được bất kỳ tin nhắn. Các/_ah/kênh/kết nối/cũng không bao giờ được gọi.

Dịch vụ kênh có được hỗ trợ với mô-đun không? Bất kỳ suy nghĩ nào về những gì tôi đang thiếu?

Trả lời

0

Bạn phải khai báo định tuyến của trình quản lý để kết nối và hủy các URL.

Handler định tuyến trong main.py:

application = webapp2.WSGIApplication([ 
    ... 
    # Define a URL routing for /_ah/channel/connected/ 
    webapp2.Route(r'/_ah/channel/connected/', 
        handler=ChannelConnectedHandler, 
        name='channel_connected') 

], debug=True, config=webapp2_config) 


# Implement class handler of /_ah/channel/connected/ 
class ChannelConnectedHandler(webapp2.RequestHandler): 
    def post(self): 
     client_id = self.request.get('from') 
     logging.info('client %s has connected!' % client_id) 
     ... 
+1

Cám ơn trả lời nhưng tôi sợ rằng không phải là vấn đề ở đây. Tôi đã không đăng mã ở đây nhưng tôi đã thêm các tuyến đường. Nó sẽ không hoạt động ở chế độ dev nếu tôi không làm vậy. –

+0

Tôi đã thêm mã đó để cho bạn biết ý tôi là gì. –

6

Theo Hỗ trợ doanh nghiệp của Google (sửa đổi chút ít so với câu trả lời liệu của họ):

  1. channel_presence dịch vụ trong nước phải được cho phép trong app.yaml.

    inbound_services: 
    - channel_presence 
    

    Kích hoạt dịch vụ trong nước này trong tập tin yaml mô-đun (ví dụ, api.yaml trong câu hỏi này) sẽ không kích hoạt dịch vụ này.

  2. Đường dẫn URL bắt đầu bằng */_ah không phải là đường dẫn có thể gửi đi và không thể được định tuyến bởi dispatch.yaml. Do đó, channel_presence Trình xử lý đường dẫn URL phải được mô tả trong app.yaml.

    handlers: 
    - url: /_ah/channel/connected/ 
        script: mymodule.application 
    
+0

Đường dây chính xác cho golang ở đây: '' script: mymodule.application'' là gì? – mattes

+0

mattes-Tôi nghĩ rằng dòng là bất khả tri ngôn ngữ, nhưng Emil- Tôi cũng đánh giá cao giải thích thêm về cách hoạt động – davidkomer

+0

Để biết thêm thông tin về 'app.yaml', hãy xem tài liệu dành riêng cho ngôn ngữ đó. Đối với Go, phiên bản có liên quan ở đây https://cloud.google.com/appengine/docs/go/config/appconfig –

0

Tôi đã tình cờ gặp vấn đề với việc sử dụng các API kênh trong mô-đun như tốt và tôi đã cố gắng để làm việc xung quanh họ sử dụng một thủ thuật tương tự như Emil đề cập đến bằng cách chuyển hướng các yêu cầu đến mô-đun.

Thiết lập hơi phức tạp hơn một chút vì tôi thực sự có 3 mô-đun, trong đó 2 mô-đun đã sử dụng API kênh và một là 'giao diện người dùng'. Một cái gì đó như thế này:

  • mô-đun frontend (mặc định)
  • mô-đun Serviceâ (sử dụng kênh api 1)
  • mô-đun serviceB (sử dụng kênh api 2)

tôi muốn để có thể lắng nghe để "thông báo" từ hai dịch vụ riêng biệt trong giao diện người dùng.

Và cách tôi quản lý để làm việc xung quanh (trong dev) là thêm chuyển hướng vào giao diện người dùng đọc mã thông báo mà tôi đã đặt trước trên mỗi dịch vụ và chuyển hướng đến từng dịch vụ.

"Tuyệt, nó hoạt động!" Tôi nghĩ nhưng sau đó khi tôi cố gắng triển khai công cụ ứng dụng, tôi nhận ra có nhiều điểm hơn ở đó vì các điểm cuối talkgadget được API trong nội bộ sử dụng dường như mong đợi một ứng dụng nguồn nhất định và do đó không cho phép liên lạc giữa các miền.

Vì vậy, tôi đã sử dụng nhiều dự án thay vì mô-đun và bằng cách đặt một iframe HTML "postMessage bridge" để giải quyết các vấn đề về miền chéo. Và vui vẻ nó hoạt động thực sự tốt và là một tác dụng phụ tôi nhận được gấp đôi số kênh "miễn phí" để sử dụng.

Tôi tìm thấy một vấn đề liên quan đến điều này ở đây có thể là thú vị cho bạn theo dõi: https://code.google.com/p/googleappengine/issues/detail?id=10293

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