2013-10-03 12 views
10

我在我的Python項目中使用App Engine的模塊。 (https://developers.google.com/appengine/docs/python/modules/#Python_Background_threadsApp Engine的Python模塊和通道服務

我也使用在米項目渠道:https://developers.google.com/appengine/docs/python/channel/

欲直接連接/斷開後的消息( '/ _ah /信道/連接/',「/ _ah /信道/斷開/ ')到我的api模塊。現在,我不能讓他們給任何一個模塊(默認或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 

注意:要清楚地說明這一切在本地開發模式下工作。

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) 

所以我的客戶(用JavaScript編寫的)職位,以我的API模塊,並打開一個通道。

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); 
    }; 

此回調函數是通過有效令牌達到的。我成功創建套接字並按預期完成此功能。在我的本地系統上,onOpened函數然後被調用,並且我從服務器接收消息。在onOpened生產是從來沒有打電話,我從來沒有收到任何消息。/_ah/channel/connected /也不會被調用。

不與模塊支持的頻道服務?有什麼想法,我失蹤了?

回答

0

您必須聲明爲連接和disconects URL的哈德勒路由。

處理程序路由在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

謝謝回答,但恐怕不是這裏的問題。我沒有在這裏發佈代碼,但我確實添加了路線。如果我沒有,它將無法在開發模式下工作。 –

+0

我添加了代碼來向你展示我的意思。 –

6

據谷歌企業支持(從原始的答案略有修改):

  1. channel_presence入站服務必須在app.yaml啓用。

    inbound_services: 
    - channel_presence 
    

    啓用模塊的YAML文件,這個入站服務(例如,在這個問題api.yaml)將不會啓用此服務。

  2. */_ah開頭的URL路徑不是可分派路徑,不能路由dispatch.yaml。因此,必須在app.yaml中描述channel_presence URL路徑處理程序。

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

這裏golang的正確路線是什麼:''script:mymodule.application''? – mattes

+0

mattes-我認爲這一行是語言不可知的,但是Emil-我也希望更多地解釋它是如何工作的 – davidkomer

+0

有關'app.yaml'的更多信息,請參閱它的語言特定文檔。對於Go,相關版本位於https://cloud.google.com/appengine/docs/go/config/appconfig –

0

我撞到使用模塊通道API以及問題,我試圖解決它們使用類似伎倆周華健提到通過重定向請求到模塊。

這是一個稍微複雜的設置,雖然因爲我實際上有3個模塊,其中2個使用Channel API,一個是'前端'。事情是這樣的:

  • 模塊前端(默認)
  • 模塊serviceA(使用通道API 1)
  • 模塊serviceB(使用通道API 2)

我希望能夠聽到前端兩個獨立服務的「通知」。

而我設法解決這個問題的方法是在前端添加重定向到前端,該前端讀取我在每個服務上添加的前綴並重定向到每個服務的標記。

「很好,它的工作原理!」我想,但是當我試圖部署到應用引擎時,我意識到這裏有更多內容,因爲Channel API內部使用的talkgadget端點似乎期望某個源應用,因此不允許跨域通信。

因此,我最終使用多個項目而不是模塊,並通過放置HTML iframe「postMessage橋」來解決跨域問題。很高興它運行得非常好,作爲副作用,我可以使用兩倍的「免費」頻道。

我發現這裏與此相關的一個問題,這可能是有趣的爲你追蹤:https://code.google.com/p/googleappengine/issues/detail?id=10293

相關問題