我假设客户端正在启动长时间运行的任务。
因此,在您开始任务之前,请从客户端向与此类似的处理程序发出 ajax 请求。这个处理程序有两个东西返回给客户端。 javascript api 用于创建通道的令牌参数,以及用于确定哪个客户端创建通道的 cid 参数。
from google.appengine.api import channel
@ae.route("/channel")
class CreateChannel(webapp2.RequestHandler):
def get(self):
cid = str(uuid.uuid4())
token = channel.create_channel(cid)
data = {
"cid":cid,
"token":token
}
self.response.write(json.dumps(data))
现在使用频道 javascript api 创建一个新频道
https://cloud.google.com/appengine/docs/python/channel/javascript
var onClosed = function(resp){
console.log("channel closed");
};
var onOpened = function(resp){
console.log("channel created");
};
var onmessage = function(resp){
console.log("The client received a message from the backend task");
console.log(resp);
};
var channel_promise = $.ajax({
url: "/channel",
method: "GET"
});
channel_promise.then(function(resp){
//this channel id is important you need to get it to the backend process so it knows which client to send the message to.
var client_id = resp.data.cid;
var channel = new goog.appengine.Channel(resp.data.token);
handler = {
'onopen': $scope.onOpened,
'onmessage': $scope.onMessage,
'onerror': function () {
},
'onclose': function () {
alert("channel closed.")
}
};
socket = channel.open(handler);
//onOpened is the callback function to call after channel has been created
socket.onopen = onOpened;
//onClose is the callback function to call after channel has been closed
socket.onclose = onClosed;
//onmessage is the callback function to call when receiving messages from your task queue
socket.onmessage = onMessage;
});
现在我们都准备好收听频道消息了。
因此,当用户单击按钮时,我们需要启动后端任务。
var letsDoSomeWorkOnClick = function(){
//make sure you pass the client id with every ajax request
$.ajax({
url: "/kickoff",
method: "POST",
params: {"cid":client_id}
});
}
现在应用引擎处理程序启动后端任务队列。我使用延迟库来做到这一点。 https://cloud.google.com/appengine/articles/deferred
@ae.route("/kickoff")
KickOffHandler(webapp2.RequestHandler):
def post(self):
cid = self.request.get("cid")
req = {}
req['cid'] = cid
task = MyLongRunningTask()
deferred.defer(task.long_runner_1, req, _queue="my-queue")
示例任务:
class MyLongRunningTask:
def long_runner_1(self,req):
# do a whole bunch of stuff
channel.send_message(req["cid"], json.dumps({"test":"letting client know task is done"})