我在我的 python 项目中使用 App Engine 模块。 ( https://developers.google.com/appengine/docs/python/modules/#Python_Background_threads )
我也在 m 项目中使用 channel :https://developers.google.com/appengine/docs/python/channel/
我想将已连接/已断开连接的发布消息('/_ah/channel/connected/'、'/_ah/channel/disconnected/')定向到我的 api 模块。现在我无法让它们出现在任何模块中(默认或 api)
应用.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
调度.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)
channel 连接处理程序
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 模块并打开一个 channel 。
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);
};
此回调函数是通过有效 token 到达的。我成功创建了套接字并按预期完成了此功能。然后在我的本地系统上调用 onOpened 函数,我从服务器接收消息。在生产中,永远不会调用 onOpened,我也从未收到任何消息。/_ah/channel/connected/也从未被调用。
模块不支持 channel 服务吗?关于我缺少的东西有什么想法吗?
最佳答案
根据 Google Enterprise 支持(从他们的原始回答中略微修改):
channel_presence
必须在app.yaml
中启用入站服务。inbound_services: - channel_presence
在模块的 yaml 文件中启用此入站服务(例如,此问题中的
api.yaml
)不会启用此服务。以
*/_ah
开头的 URL 路径不是可调度路径,不能通过dispatch.yaml
进行路由。因此,必须在app.yaml
中描述channel_presence
URL 路径处理程序。handlers: - url: /_ah/channel/connected/ script: mymodule.application
关于google-app-engine - App Engine Python 模块和 channel 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19163056/