II. CÁC BƯỚC CÀI ĐẶ T:
3. Viết code cho ứng dụng
- Tạo project mới : vào click chuột phải vào biểu tượng chữ g rồi chọn New web Application Project…
- Thêm file class có tên FriendServlet.java ở src/com.google.appengine.codelab package com.google.appengine.codelab; import java.io.IOException; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.appengine.api.channel.ChannelMessage; import com.google.appengine.api.channel.ChannelService;
@SuppressWarnings("serial")
public class FriendServlet extends HttpServlet { private static ChannelService channelService = ChannelServiceFactory.getChannelService(); private static final Logger logger =
Logger.getLogger(FriendServlet.class.getCanonicalName());
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user = request.getParameter("userid"); response.setContentType("text/xml");
String outputTxt = "<data>\n" ;
FriendStore friendStore = FriendStore.getInstance();
if(!friendStore.getFriends().contains(user)){
logger.log(Level.INFO,"User {0} is added to list of users",user); friendStore.addNewFriend(user);
} else{
logger.log(Level.INFO,"User {0} is already added to list of users\n" +"hence, not adding now",user);
}
Iterator<String> friendList = friendStore.getFriends().iterator();
logger.log(Level.INFO,"All the users list is written to the output and "+"the message about new user sent to all other users");
//Add all the users logged in already to the new user friends list // and also update all of them about the new user
while(friendList.hasNext()){
String friend = friendList.next() ; if(!friend.equals(user)){
outputTxt +="<friend><name>" + friend +"</name></friend>\n"; channelService.sendMessage(
new ChannelMessage(friend,"<data>" + "<type>updateFriendList</type>" + "<message>"+user+"</message>" + "<from>Server</from>" + "</data>"));
} } outputTxt += "</data>\n"; response.getWriter().print(outputTxt); } }
- Thêm file class có tên FriendStore.java ở src/com.google.appengine.codelab package com.google.appengine.codelab; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; public class FriendStore {
private Set<String> friendsList = new HashSet<String>(); private static FriendStore instance ;
private static final Logger logger =
Logger.getLogger(FriendServlet.class.getCanonicalName()); private FriendStore(){
}
public static FriendStore getInstance(){ if(instance==null)
instance = new FriendStore(); return instance;
}
void addNewFriend(String user){
logger.log(Level.INFO,"User {0} is added to the list",user); friendsList.add(user);
}
void removeFriend(String user){
logger.log(Level.INFO,"User {0} is removed from the list",user); friendsList.remove(user);
logger.log(Level.INFO,"Users sorted and the set returned"); return new TreeSet<String>(friendsList);
} }
- Thêm file class có tên MessageServlet.java ở src/com.google.appengine.codelab package com.google.appengine.codelab; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.appengine.api.channel.ChannelFailureException; import com.google.appengine.api.channel.ChannelMessage; import com.google.appengine.api.channel.ChannelService; import com.google.appengine.api.channel.ChannelServiceFactory; @SuppressWarnings("serial")
public class MessageServlet extends HttpServlet {
private static final Logger logger =
Logger.getLogger(MessageServlet.class.getCanonicalName());
private static ChannelService channelService = ChannelServiceFactory.getChannelService();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String message = request.getParameter("message"); String user = request.getParameter("to");
String from = request.getParameter("from");
if (user != null && !user.equals("") && message != null && !message.equals("")) {
try{
String outputMessage ="<data>" +
"<type>updateChatBox</type>" + "<message>"+message+"</message>" + "<from>"+from+"</from>" +
logger.log(Level.INFO,"sending message into the channel"); sendMessageToChannel(user, outputMessage);
} catch (ChannelFailureException channelFailure) {
logger.log(Level.WARNING, "Failed in sending message to channel"); response.getWriter().print("OFFLINE");
} catch (Exception e) {
logger.log(Level.WARNING, "Unknow error while sending message to the channel");
response.getWriter().print("OFFLINE"); }
} }
public void sendMessageToChannel(String user,String message) throws ChannelFailureException{
channelService.sendMessage(new ChannelMessage(user, message)); }
}
- Thêm file class có tên TokenServlet.java ở src/com.google.appengine.codelab package com.google.appengine.codelab; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.appengine.api.channel.ChannelFailureException; import com.google.appengine.api.channel.ChannelService; import com.google.appengine.api.channel.ChannelServiceFactory; @SuppressWarnings("serial")
public class TokenServlet extends HttpServlet { private static final Logger logger =
ChannelServiceFactory.getChannelService();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userId = request.getParameter("userid"); if (userId != null && !"".equals(userId)) { String token = createChannel(userId); writeIntoChannel(response,token); }
}
public String createChannel(String userId){ try{
logger.log(Level.INFO, "Creating a channel for {0}",userId); return channelService.createChannel(userId);
} catch(ChannelFailureException channelFailureException){ logger.log(Level.WARNING, "Error creating the channel"); return null;
} catch(Exception otherException){
logger.log(Level.WARNING, "Unknown exception while creating channel"); return null;
} }
public void writeIntoChannel(HttpServletResponse response, String token){ try{
logger.log(Level.INFO, "Writing the token {0} to the output",token); response.getWriter().print(token);
} catch(IOException ioException){
logger.log(Level.WARNING, "Exception while writing output "); } catch(Exception exception){
logger.log(Level.WARNING, "Unknow exception while writing output "); }
} }
#loginPage,#chatMessagesPage,#friendsListPage{ display:none; } .chatbox{ border:1px solid #bbb; width:230px; padding:0; /* 10px 10px 10px ;*/ margin-top:5px; margin-left:10px; float:right; background:#fff; } .chatTextArea{ border:1px solid #bbb; margin-top:10px; } .closeButton{ color:#fff; float:right; cursor:pointer; padding:2px 4px; font-weight:bold; } p.headerMessage{ line-height: 100%; padding:1px 0; height:1em; } .chatBoxMessagesContainer{ padding-left:5px; height:225px; overflow:auto; } #chats{ position:fixed; bottom:2%; right:2%; border:0px; height:300px; background:transparent; } .headerContainer{ padding:4px; background:#357EC7; color:#fff; }
Tạo file index.html ở war/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Chat24gio</title>
<script language="javascript" src='AjaxUtil.js'></script> <link type="text/css" rel="stylesheet" href="style.css" /> </head>
<body> <div>
<div style="margin-top: 0px; padding-bottom: 10px; display:
table;">
<img
style="float: left; padding-right: 13px; padding- bottom: 5px; padding-top: 6px;"
src="images/appengine_lowres.png">
<div style="display: table-cell; vertical-align:
middle;">
<div style="font-size: 170%; font-weight: bold; padding-top: 10px;"> Ứng dụng chat24gio<br> </div> </div> </div> </div> <div id="gc-topnav"
style="border-top: 0px solid #3366CC; font-size: 0.5em;"> <ul class="gc-topnav-tabs" id="docs">
</ul> </div> <div>
<div class="g-section g-tpl-170">
<div id="gc-toc" class="g-unit g-first" style="width:
73px !important; padding: 10px 12px !important;"> <div id="leftPanelInit">
<div style="padding-bottom: 3px;">
<input id="initLoginBtn" type="button" title="Login" class="gsc-search-button" name="sa" style="width: 66px;" value="Login" /> </div> </div> <div id="friendsListPage"> </div> </div>
<div id="gc-pagecontent" class="g-unit"
style="position: relative; margin: 0 0 0 95px !important;">
<div id="parent-content-div" style="height:
600px;">
<div id="welcomePage" class="g-unit" style="position: relative; display:
block; margin: 0 !important; border: none !important; padding-top: 16px;" id="welcomeView">
<div align="center">
<h3 style="font-weight: normal; padding-top: 150px;">
Chào mừng các bạn đến với chat24gio</h3>
</div> </div>
<div id="loginPage" style="display: none;"> <h1 class="page_title" style="margin:
0px 12px !important;">Đăng nhập
</h1>
<div>
<table width="200" border="0" style="border: none !important;"
cellspacing="0" cellpadding="0"> <tr style="border: none !important;"> <td width="148" nowrap="nowrap"
style="border: none !important;"><b>Tên đăng nhập </b> </td>
<td width="52" style="border: none !important;">
<input type="text" style="width:185px;" maxlength="2048" id="userid" name="userid" />
</td> </tr>
<tr style="border:
none !important;">
<td nowrap="nowrap" style="border: none !important;"> </td>
<td style="border: none !important;"><div
style="padding-bottom: 3px;">
<input type="button" style="width: 66px;" title="List" value="Login" id="loginBtn"/>
<input type="button" style="width: 66px;" title="List" value="Reset" id="resetBtn"/>
</div> </td> </tr> </table> </div> </div> </div> <div id="chats"> <div id="chatMessagesPage"> </div> </div> </div>
<div id="gc-collapsible" style="height: 600px;" class=""></div> </div> <!-- end gc-pagecontent --> </div> </div> <div id="gc-topnav"
style="border-top: 0px solid #3366CC; font-size: 0.5em;"> <ul class="gc-topnav-tabs" id="docs">
</ul> </div>
Tạo file AjaxUtil.js
var userid;
window.onload= init;
//general ajax function for all requests
function makeRequest(url,async) {
var httpRequest;
if (window.XMLHttpRequest) {
// Mozilla, Safari, ...
httpRequest = new XMLHttpRequest(); } else if (window.ActiveXObject) {
// IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) {} }
}
if (!httpRequest) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false; }
httpRequest.open('POST', url,async); httpRequest.send();
return httpRequest; }
function init(){
document.getElementById("initLoginBtn").onclick = showLoginPage; document.getElementById("loginBtn").onclick = loginUser;
}
showLoginPage = function(){
document.getElementById("loginPage").style.display = "block"; document.getElementById("welcomePage").style.display = "none"; document.getElementById("userid").onkeydown = function(event){
if (event.keyCode == 13){ loginUser();
} }
document.getElementById("userid").focus(); };
loginUser = function(){
document.getElementById("loginPage").style.display = "none";
document.getElementById("chatMessagesPage").style.display = "block"; userid = document.getElementById("userid").value ;
document.getElementById("leftPanelInit").style.display = "none"; document.getElementById("friendsListPage").style.display = "block"; requestToken();
displayFriendList(); };
requestToken = function(){
var getTokenURI = '/gettoken?userid=' + userid ;
var httpRequest = makeRequest(getTokenURI,true); httpRequest.onreadystatechange = function(){
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
openChannel(httpRequest.responseText); }else {
alert('There was a problem with the request.'); }
} }
};
openChannel = function(token) {
var channel = new goog.appengine.Channel(token);
var socket = channel.open(); socket.onopen = onSocketOpen;
socket.onmessage = onSocketMessage; socket.onerror = onSocketError; socket.onclose = onSocketClose; };
onSocketError = function(error){
alert("Error is <br/>"+error.description+" <br /> and HTML code"+error.code); }; onSocketOpen = function() { // socket opened }; onSocketClose = function() {
alert("Socket Connection closed"); };
onSocketMessage = function(message) {
var messageXML = ((new DOMParser()).parseFromString(message.data,
"text/xml"));
var messageType =
messageXML.documentElement.getElementsByTagName("type")[0].firstChild.nodeValue;
if(messageType == "updateFriendList"){
addToFriends(messageXML.documentElement.getElementsByTagName("message")[0]. firstChild.nodeValue);
}else if(messageType == "updateChatBox"){
var friend =
messageXML.documentElement.getElementsByTagName("from")[0].firstChild.nodeValue ; document.getElementById(friend+"chatBox").style.display="block"; updateChatBox(messageXML.documentElement.getElementsByTagName("message")[0] .firstChild.nodeValue,friend);
} };
displayFriendList =function(){
var txt = document.createElement("div");
txt.innerHTML = "<p> Logged in as <b>"+userid+"</b><p><hr />"; document.getElementById("friendsListPage").appendChild(txt);
var getFriendListURI = 'getFriendList?userid='+ userid;
var friendListXML =
httpRequest.responseXML.getElementsByTagName("friend");
for( var i =0 ; i < friendListXML.length ; i++){
addToFriends(friendListXML[i].getElementsByTagName("name")[0].firstChild.no deValue);
} }else {
alert('There was a problem with the request.'); }
} };
var friendsList= new Array();
addToFriends = function(friend){
//check if the user already added
var contains = false;
for(var i = 0 ; i < friendsList.length ; i++){
if(friendsList[i]==friend){ contains=true; break; } } if(!contains){ friendsList.push(friend);
var a = "<a id='"+friend+"'>"+friend+"</a>";
var txt = document.createElement("div"); txt.innerHTML = a;
txt.style.cursor="pointer";
txt.setAttribute("onclick","openChat(\""+friend+"\");"); document.getElementById("friendsListPage").appendChild(txt);
//adding chat boxes
var chatBox = document.createElement("div"); chatBox.style.display = "none";
chatBox.setAttribute("id",friend+"chatBox"); chatBox.setAttribute("class","chatbox");
var headerContainer = document.createElement("div"); headerContainer.setAttribute("class","headerContainer");
var closeButton = document.createElement("a"); closeButton.innerHTML="X";
closeButton.setAttribute("class","closeButton");
closeButton.setAttribute("onclick","closeWindow('"+friend+"')"); headerContainer.appendChild(closeButton);
var headerMessage = document.createElement("p"); headerMessage.setAttribute("class","headerMessage");
headerMessage.innerHTML = "<b>"+friend+"</b><br /><br />"; headerContainer.appendChild(headerMessage);
chatBox.appendChild(headerContainer);
var chatBoxMessagesContainer = document.createElement("div");
chatBoxMessagesContainer.setAttribute("id",friend+"chatBoxMessageContainer"
);
chatBoxMessagesContainer.setAttribute("class","chatBoxMessagesContainer"); chatBox.appendChild(chatBoxMessagesContainer);
var chatBoxMessagesTextarea = document.createElement("div");
var textareaStr = "<textarea id='"+friend+"textarea' cols='25' rows='2'" +
"onkeydown=\"if(event.keyCode == 13){sendMessage('"+friend+"') }\"" +
"class=\"chatTextArea\"" +
" ></textarea>";
chatBox.innerHTML += textareaStr ;
var submitButton = document.createElement("input"); submitButton.setAttribute("type","button");
submitButton.setAttribute("value","send");
submitButton.setAttribute("id",friend+"submitButton");
submitButton.setAttribute("onclick","sendMessage('"+friend+"')"); chatBox.appendChild(document.createElement("br"));
document.getElementById("chatMessagesPage").appendChild(chatBox); }
};
closeWindow = function(friend){
document.getElementById(friend+"chatBox").style.display="none"; }
openChat = function(friend){
document.getElementById(friend+"chatBox").style.display = "block"; document.getElementById(friend+"textarea").focus();
}
sendMessage = function(friend){
var message = document.getElementById(friend+"textarea").value;
var sendMessageURI = '/message?message=' + message + '&to=' + friend+'&from='+userid ;
var httpRequest = makeRequest(sendMessageURI,true); httpRequest.onreadystatechange = function(){
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) { }else {
alert('There was a problem with the request.'); }
} }
var mesgDiv = document.createElement("a");
mesgDiv.innerHTML ="<b>me</b>: "+ message+"<br />";
var abc = document.getElementById(friend+"chatBoxMessageContainer");
if(abc)
abc.appendChild(mesgDiv);
else
alert("error");
document.getElementById(friend+"textarea").value=""; }
updateChatBox = function(message,from){
var mesgDiv = document.createElement("a");
mesgDiv.innerHTML ="<b>"+from+"</b>: "+ message+"<br />";
var abc = document.getElementById(from+"chatBoxMessageContainer");
if(abc)
abc.appendChild(mesgDiv);
else
alert("error"); };
-Tạo file appengine-app.xml ở war/WEB-INI
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <application>chat24gio</application>
<version>1</version>
<threadsafe>true</threadsafe>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-
INF/logging.properties"/> </system-properties> </appengine-web-app>
(Với chat24gio là tên ứng dụng bạn đã tạo trên google appengine) - Tạo file web.xml ở war/WEB-INI
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet>
<servlet-name>TokenServlet</servlet-name> <servlet-
class>com.google.appengine.codelab.TokenServlet</servlet-class> </servlet>
<servlet-mapping>
<servlet-name>TokenServlet</servlet-name> <url-pattern>/gettoken/*</url-pattern> </servlet-mapping>
<servlet>
<servlet-name>MessageServlet</servlet-name>
<servlet-class>com.google.appengine.codelab.MessageServlet</servlet- class>
</servlet>
<servlet-mapping>
<servlet-name>MessageServlet</servlet-name>
<url-pattern>/message/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>FriendServlet</servlet-name>
<servlet-class>com.google.appengine.codelab.FriendServlet</servlet- class>
</servlet>
<servlet-mapping>
<servlet-name>FriendServlet</servlet-name>
<url-pattern>/getFriendList/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file> </welcome-file-list>
4.Triển khai ứng dụng :
Để upload code và các file chương trình của bạn lên Google App Engine,bạn click chuột phải vào project chọn google,rồi chọn Deloy to App engine
Khi có thông báo Deployment completed successfully,như thế là bạn đã upload thành công Lưu ý : Bạn phải nhập tài khoản gmail mà bạn đã tạo AppEngine ở trên
Muốn chạy ứng dụng,bạn chỉ cần gõ địa chỉ chat24gio.appspot.com vào thanh địa chỉ web là có thể chạy được ứng dụng rồi.
Các bạn thiết kế websie hay viết các chương trình đòi hỏi phải tạo cơ sở dữ liệu và nơi lưu trữ cơ sở dữ liệu. Đối với ứng dụng này bạn không cần phải quan tâm đến cơ sở dữ liệu lưu ở đâu và truy vấn như thế nào. Bởi vì điều này đã có Google app engine làm
CHƯƠNG IV KẾT LUẬN
Qua nghiên cứu ứng dụng điện toán đám mây trên google appengine ta thấy rằng :
Điện toán đám mây là một xu hướng phát triển mới của các trung tâm dữ liệu (data center). Các máy chủ trong trung tâm dữ liệu được ảo hóa bằng các công nghệ ảo hóa và được cấp phát động tùy theo nhu cầu sử dụng tài nguyên của người dùng nhằm thỏa mãn một sự đồng thuận cụ thể ở mức dịch vụ.
Điện toán đám mây cung cấp cho người dùng nhiều loại hình dịch vụ khác nhau như dịch vụ cơ sở hạ tầng, dịch vụ nền tảng, dịch vụ phần mềm.
Ở đây,Google App Engine là giải pháp cho vấn đề điện toán đám mây. Google cung cấp sẵn một hệ thống máy chủ điện toán đám mây, và người lập trình sẽ viết ứng dụng của mình lên đó. Ứng dụng này sẽ chạy trên đám mây của Google.
Sau khi xây dựng ứng dụng với google appengine thì nhóm có một số nhận xét sau: Đạt được :
- Đã xây dựng được ứng dụng demo dựa trên gói thư viện của google. - ứng dụng nhỏ gọn ,dễ sử dụng.
Hướng phát triển:
Vì điện toán đám mây là một đề tài lớn, đã và đang được nhiều ông lớn như google , intel ,microsoft…. nghiên cứu và phát triển. cho nên trong thời gian ngắn chúng em chỉ có thể đáp ứng xây dựng demo nho nhỏ,chứ chưa có thể nào xây dựng một ứng dụng lớn cho công ty hay doanh nghiệp.Trong tương lai,chúng em có thể tiếp tục phát triển lên và áp dụng đăng nhập bằng chính tài khoản website của mình.
TÀI LIỆU THAM KHẢO
[1] Website
http://code.google.com/intl/vi-VN/appengine/ http://congdongit.org/
http://vi.wikipedia.org/wiki/Điện_toán_đám_mây (xem ngày 20/3/2013)
http://googcloudlabs.appspot.com/ [2] Ebook
- Hành trình đến với Điện toán Đám mây riêng_ Lê Hùng
- Programming Google appengine_Dan snaderson
- Cloud Computer Primer_ Sun Microsystems
- Bí mật phía sau điện toán đám mấy_ Marc Benioff. Carlye Adler.