【问题标题】:Google Channel API sending message with tokenGoogle Channel API 使用令牌发送消息
【发布时间】:2013-02-17 23:50:07
【问题描述】:

在文档中说“client_id”部分实际上可以是令牌,但它不起作用。有人知道为什么吗?

https://developers.google.com/appengine/docs/python/channel/functions

如果 client_id 参数实际上是 create_channel 调用返回的令牌,则 send_message 可用于不同版本的应用程序。例如,您可以在前端创建通道,然后从应用程序的后端发送消息。

我想使用它的原因是因为我也想向匿名用户发送消息,而不需要他们登录。如果令牌不起作用,我不知道是否可以为他们分配一个“client_id”。

这就是我创建令牌的方式

    user = users.get_current_user()

    if user:
        token = channel.create_channel(user.user_id())
    else:
        token = channel.create_channel(str(uuid.uuid4()))

然后注入客户端

template_values = {
        'token' : token,
    }

在客户端打开通道

      openChannel = function() {
    var token = '{{ token }}';
    var channel = new goog.appengine.Channel(token);
    var handler = {
      'onopen': onOpened,
      'onmessage': onMessage,
      'onerror': function() {},
      'onclose': function() {}
    };
    var socket = channel.open(handler);
    socket.onopen = onOpened;
    socket.onmessage = onMessage;
  }

现在发送消息

var xhr = new XMLHttpRequest();
xhr.open('POST', path, true);
xhr.send();

在服务器中, 当收到消息时,使用令牌发回消息

channel.send_message(token, someMessage)

返回客户端

onMessage = function(m) {
alert("you have some message");     
}

如果在调用 send_message 时使用 client_id() 而不是令牌,则此序列可以正常工作

【问题讨论】:

  • “它不起作用”不是很具有描述性。什么不起作用?它怎么不工作?您期望什么行为,您实际看到什么行为?
  • @Amber 我期待与使用 client_id 相同的行为。当我使用之前创建的令牌调用 channel.send_message(token, message) 时,在客户端基本上我没有收到任何消息。另一方面,使用client_id,我可以收到我发送的消息。
  • 尝试显示一些代码,了解如何生成令牌并传递它。
  • @amber 在问题中添加了我在做什么
  • 请求之间的令牌存储在哪里?

标签: google-app-engine token channel-api


【解决方案1】:

针对 btevfik 最初的问题:允许在 send_message 中使用令牌或 client_id 是 1.7.5(最近)发布的一项功能。有些人可能还不熟悉它,因此他们建议使用 client_id。两者都应该工作!

我在您的代码中唯一能看到的是,您不应该依赖令牌变量在两个请求之间保持正确。他们甚至可能不会登陆同一个应用程序实例。如果您与更多详细信息分享您的代码,我可能会发现一些东西。正确的方法是将令牌存储在数据存储中,或者在您发送将触发返回消息的消息时将其作为参数从客户端传递。

此功能的目的是允许人们从后端(或其他版本)发送消息。以前是不可能的,而现在如果你直接使用令牌而不是 client_id,你就可以做到。

【讨论】:

  • 感谢您的回复。由于我之前无法让我的应用程序发送带有令牌的消息,因此我使用了 client_id。它现在工作正常。对于已登录的用户,发送消息很容易,因为您需要做的就是获取当前用户的用户 ID,但是对于匿名用户,因为我为他们分配了一个任意的 client_id,所以这并不容易,所以现在我我将此客户端 ID 存储在可以检索的 cookie 中。当我有时间时,我可能会再次检查代码。如果有的话,再问任何问题。再次感谢
【解决方案2】:

这篇文章已经发布了很长时间,但只是对您对令牌全局变量的使用感到好奇?

我没有看到这段代码:

global token

在设置令牌之前

user = users.get_current_user()

if user:
    token = channel.create_channel(user.user_id())
else:
    token = channel.create_channel(str(uuid.uuid4()))

如果缺少该代码,则token 将设置在上述函数的本地范围内,而不是全局范围内。因此,稍后使用的令牌值将是 None(或令牌初始化时使用的任何值。)

只是一个想法,如果它仍然相关的话。

【讨论】:

  • 我刚刚检查了代码。我想你是对的。它没有global。我不知道为什么我没有看到它。这只是我自己尝试应用程序引擎的一个小项目。将全局分配给令牌可能会解决我最初的问题,但实际上并没有尝试过。不过谢谢。
【解决方案3】:

我认为你在这里实际上没有问题。

您可以向已登录或未登录的用户发送消息。

我认为您遇到的问题是知道有多种方法可以使用通道 API re:tokens。

https://developers.google.com/appengine/docs/python/channel/overview#Life_of_a_Typical_Channel_Message

在此示例中,它显示了 JavaScript 客户端显式请求令牌并将其客户端 ID 发送到服务器。相反,您可以选择将您的应用程序设计为在页面加载到浏览器之前将令牌注入客户端,或者如果愿意,可以选择其他一些实现。

此图显示了在服务器上创建通道。 在这 例如,它显示 JavaScript 客户端显式请求令牌 并将其客户端 ID 发送到服务器。相比之下,您可以选择 设计您的应用程序以在之前将令牌注入客户端 页面在浏览器中加载,或者其他一些实现,如果 首选。

这是我的演示实现,希望对您有所帮助:https://github.com/Paul1234321/channelapidemo.git

这是在 GAE 上创建频道的代码:

  client_id = str(uuid.uuid4()).replace("-",'')
  channel_token = channel.create_channel(client_id)

在 JS 中:

channel = new goog.appengine.Channel('{{ token }}');

看看它的实际效果:http://pppredictor.appspot.com/

【讨论】:

  • 登录与否,我无法使用令牌发送消息。 client_id 似乎只来自登录用户。除非有办法将唯一的 client_ids 分配给匿名用户。我不认为显式请求令牌与注入令牌的实现有什么区别。
  • 频道 API 与用户是否登录无关,从我的演示中可以看出。我怀疑您正在生成的 UUID 中的非字母数字字符可能是问题所在,请尝试将它们剥离?令牌用于创建通道,而不是发送消息。 javascript 需要令牌来创建通道,您使用客户端 ID 发送消息。
  • 我已经编辑了我的答案,建议从 UUID 中去掉 -。
  • 好的,谢谢。所以你不能发送带有令牌的消息,即使它在文档中说你可以
  • 是的,您使用令牌创建频道并使用 id 发送消息。
【解决方案4】:

您不应将特定于请求的值存储在全局变量中。将它们存储在 cookie 中或将它们作为请求参数传递。

【讨论】:

  • 那会改变结果吗?
猜你喜欢
  • 2016-11-29
  • 2020-11-25
  • 2022-06-23
  • 2013-06-04
  • 2017-10-12
  • 1970-01-01
  • 2014-04-16
  • 2017-04-28
  • 2012-04-10
相关资源
最近更新 更多