簡體   English   中英

Google App Engine頻道API

[英]Google App Engine Channel API

我正在嘗試學習GAE的通道API(使用Java),但是我不知道從哪里開始。

我經歷了Channel API Overview(Java),但為簡潔起見,此處發布的代碼並不完整。

而且由於我是新手,如果可以使用完整的示例代碼,這將非常有幫助。

謝謝,Shrey

您鏈接到的Channel API Overview中的代碼已經相當完整,只是到處都是。 我承認,一旦您理解了它,我覺得它比他們看起來要簡單得多,但是我很高興他們犯錯了提供過多信息的一面。

在不增加多余信息的情況下,很難為此提供一個完整的解決方案,因為您使用Channel API的某些方式在某種程度上取決於您現有應用程序的基礎結構。 因此,我試圖對AppEngine文檔提供的內容進行詳細說明,以便希望您能更好地理解。 如有任何疑問,您可以通過注釋提出具體問題。

首先,一些詞匯:

  • 頻道消息:您希望發送給客戶端的消息(可能是您最初使用頻道API的原因)。
  • 通道密鑰:用戶唯一的字符串,以及用戶嘗試發送消息的范圍。
  • 通道令牌:任何客戶端唯一的字符串。 每2小時每個客戶1個渠道令牌。
  • 頻道服務: AppEngine服務器端類,提供了一種創建頻道並通過其發送頻道消息的方法。

在服務器上,您將需要執行以下操作:

ChannelService channelService = ChannelServiceFactory.getChannelService();

// The channelKey can be generated in any way that you want, as long as it remains
// unique to the user.
String channelKey = "xyz";
String token = channelService.createChannel(channelKey);

獲得令牌后,您只需要一些方法即可將其獲取到客戶端代碼。 您鏈接到的AppEngine文檔通過從Java servlet提供HTML並調用index.replaceAll("\\\\{\\\\{ token \\\\}\\\\}", token)

他們的工作方式是將文字字符串{{ token }}放入他們的JavaScript代碼中(如下所示),因此無論{{ token }}出現在JavaScript代碼中的什么地方,它都將被替換為由上面的channelService.createChannel(...)調用生成的實際令牌。 請注意,您不需要將令牌注入以這種方式提供服務的客戶端代碼中,但這是一個很好的起點,因為這就是他們的工作方式(並記錄了下來)。


現在,您已經將令牌注入到JavaScript中,您需要將帶有通道令牌的代碼獲取到client (請注意,如上所述,您也可以僅將令牌獲得給客戶端,並以這種方式創建通道) 他們擁有的代碼是:

<body>
  <script>
    channel = new goog.appengine.Channel('{{ token }}');
    socket = channel.open();
    socket.onopen = onOpened;
    socket.onmessage = onMessage;
    socket.onerror = onError;
    socket.onclose = onClose;
  </script>
</body>

他們刪節了有關如何從服務器上的文件讀取內容的詳細信息,但是同樣,您可以按照自己喜歡的任何方式進行操作。 您還可以在JavaServlet中使用resp.getWriter().print(index)從字面上打印String,其中index是存儲上面列出的HTML / JavaScript內容的String。 就像我最初說的那樣,最適合您應用程序現有基礎架構的還有很多事情要做。

它們旨在讓您定義自己的JavaScript函數onOpenedonMessageonErroronClose ,分別在打開通道,接收消息,遇到錯誤或關閉通道時調用它們。 您可能希望僅創建幼稚的實現以更好地了解發生了什么:

function onOpened() {
    alert("Channel opened!");
}

function onMessage(msg) {
    alert(msg.data);
}

function onError(err) {
    alert(err);
}

function onClose() {
    alert("Channel closed!");
}

我仍然建議將它們分離為單獨的功能,以便您可以更輕松地擴展它們以進行試驗並弄清楚。 有關JavaScript API的更多詳細信息,請參見Channel API JavaScript Reference


您需要建立一種機制來獲取要從客戶端發送到服務器的數據 再一次,您希望如何操作都無關緊要。 AppEngine文檔建議設置XMLHttpRequest來實現此目的。

sendMessage = function(path, opt_param) {
  path += '?g=' + state.game_key;
  if (opt_param) {
    path += '&' + opt_param;
  }
  var xhr = new XMLHttpRequest();
  xhr.open('POST', path, true);
  xhr.send();
};

在這里, opt_param只是一串可選參數,格式為x=1&y=2&z=3 這是他們為示例Tic-Tac-Toe應用程序構建的所有基礎結構,對Channel API的功能並不關鍵; 就像我說的,您可以根據需要撥打此電話。

path是您的Servlet的路徑(您需要在web.xml文件中進行設置),該路徑應該處理消息的發送和接收(請參閱以下部分)。


從客戶端向服務器發送消息之后,您將需要一個servlet,該servlet可以使用相同的通道密鑰將更新發送到所有客戶端

ChannelService channelService = ChannelServiceFactory.getChannelService();

// This channelKey needs to be the same as the one in the first section above.
String channelKey = "xyz"

// This is what actually sends the message.
channelService.sendMessage(new ChannelMessage(channelKey, "Hello World!"));

上面的channelService.sendMessage(...)調用實際上是發送消息的地方,因此上一節中定義的onMessage函數可以接收到該消息。


我希望這個答案足夠完整(就此而言,是正確的),足以幫助您入門。 他們放入文檔中的大部分內容(以及我在此處的代碼)都可以進行復制和粘貼,只需稍作調整即可。

我是StackOverflow的新手,不確定該問題是否仍然存在,但是如果您仍在使用Google的Channel API(ServerSide(Java)和Client(Java))尋找完整的Java示例,則可以找到詳細的說明在這里寫過: http : //masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/

它列出了創建通道(客戶端和服務器),在通道上發送消息(客戶端和服務器)以及Java客戶端可以用來與通道交互的簡單框架的所有內容。 我也很難理解Google的文檔並理解所有內容。 我希望這些信息仍然有用並且有用:-)

完整的源代碼和聊天示例可以在GitHub上找到: https : //github.com/gvsumasl/jacc

這是一些示例代碼,希望對您有所幫助:-)


Java客戶端通道創建(使用ChannelAPI框架:Jacc)

ChatListener chatListener = new ChatListener();
ChannelAPI channel = new ChannelAPI("http://localhost:8888", "key", chatListener);
channel.open();

Java服務器端通道創建:

public class ChatChannelServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {    
    String channelKey = req.getParameter("c");

    //Create a Channel using the 'channelKey' we received from the client
    ChannelService channelService = ChannelServiceFactory.getChannelService();
    String token = channelService.createChannel(channelKey);

    //Send the client the 'token' + the 'channelKey' this way the client can start using the new channel
    resp.setContentType("text/html");
    StringBuffer sb = new StringBuffer();
    sb.append("{ \"channelKey\":\"" + channelKey + "\",\"token\":\"" + token + "\"}");

    resp.getWriter().write(sb.toString());
  }
}

Java客戶端消息發送(使用ChannelAPI框架:Jacc)

/***
* Sends your message on the open channel
* @param message
*/
public void sendMessage(String message){
try {
        channel.send(message, "/chat");
    } catch (IOException e) {
        System.out.println("Problem Sending the Message");
    }
}

Java服務器端消息發送:

public class ChatServlet extends HttpServlet {
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String channelKey = req.getParameter("channelKey");
    String message = req.getParameter("message");

    //Send a message based on the 'channelKey' any channel with this key will receive the message
    ChannelService channelService = ChannelServiceFactory.getChannelService();
    channelService.sendMessage(new ChannelMessage(channelKey, message));
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM