앱엔진 짱이네요-_-
속도만 빨랐다면 호스팅을 여기로 옮겨도 뭐 문제가 없을 듯. 시스템적으로는 구글이 다 관리해주고, 개발환경도 매우 편하니...(하지만, DB 접근이 방식이 틀려서 힘든면도 있지만ㅠ)

pc랑 android랑 뭔가 싱크맺는 뭐 그런거 만드려다보니 여기까지 와버렸네요-_- 이걸 통해서 하면 좋을 것 같아서^^

암튼, Channel API를 제공하는데, 원하는 채널을 생성해서 그곳 페이지로 접속한 사용자들끼리 메세지를 주고 받을 수 있게 됩니다. 

앱엔진 채널부분 문서입니다.
http://code.google.com/intl/ko-KR/appengine/docs/java/channel/

보면 JavaAPI랑 JavascriptAPI 두개 있는데, 클래스도 몇 개 없습니다.
Java에서는 ChannelService를 가져와서 createChannel로 채널을 만든 뒤에, sendMessage함수로 메세지만 보내면 됩니다.
Javascript에서는 goog.appengine.Channel이라는 클래스가 존재하는데, 이걸로 오픈하고 메세지 받으면 됩니다.

일단..... 나중에 쓰려고 만든거다보니 Spring3.0과 jQuery가 들어갔네요-_-
http://mudchobo.tistory.com/470 이거 참조해서 환경 구축을 하면 됩니다~^^

ChannelController.java

package com.mudchobo.apps.exchangepp.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;

@Controller
@RequestMapping("/channeltest")
public class ChannelController {
	
	private String channelName = "test";
	
	@RequestMapping(value="/test", method=RequestMethod.GET)
	public String test(Model model){
		ChannelService channelService = ChannelServiceFactory.getChannelService();
		String token = channelService.createChannel(channelName);
		model.addAttribute("token", token);
		return "test";
	}
	
	@RequestMapping(value="/open", method=RequestMethod.POST)
	@ResponseBody
	public String openChat(){
		ChannelService channelService = ChannelServiceFactory.getChannelService();
		channelService.sendMessage(new ChannelMessage(channelName, "open"));
		return "";
	}
	
	@RequestMapping(value="/send", method=RequestMethod.POST)
	@ResponseBody
	public String sendChat(@RequestParam("msg") String msg){
		System.out.println("message = " + msg);
		try {
			ChannelService channelService = ChannelServiceFactory.getChannelService();
			channelService.sendMessage(new ChannelMessage(channelName, URLEncoder.encode(msg, "UTF-8")));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}
}
최초 접속페이지는 /test 입니다.
여기서 채널을 생성해줍니다. 이 생성해서 나온 토큰을 client로 전달합니다. 그러면 그 client에서 goog.appengine.Channel("토큰값");을 통해 Channel을 생성합니다. 그러면 커넥션을 맺고 있게 되는겁니다.

클라이언트부분
test.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false" %>
<!doctype html>
<html>
	<head>
		<script src="/_ah/channel/jsapi"></script>
		<script src="/js/lib/jquery-1.4.4.min.js" type="text/javascript"></script>
		<script type="text/javascript">
			var sendMessage = function(path, msg){
				var xhr = new XMLHttpRequest();
				xhr.open("POST", "/apps/channeltest/" + path + "?msg=" + encodeURIComponent(msg), true);
				xhr.send();
			}
			
			var onOpen = function(){
				sendMessage("open");
			};
			var onMessage = function(m){
				var msg = decodeURIComponent(m.data.split("+").join(" "));
				$("#message_box ul").append("<li>" + msg + "</li>");
				$("#message_box").scrollTop(999999999);
			};
			var onError = function(){
				alert("error");
			};
			var onClose = function(){
				alert("close");
			};
			
			$(document).ready(function(){
				var channel = new goog.appengine.Channel("${token}");
				var socket = channel.open();
				socket.onopen = onOpen;
				socket.onmessage = onMessage;
				socket.onerror = onError;
				socket.onclose = onClose;
				
				$("#send_btn").click(function(){
					sendMessage("send", $("#message").val());
					$("#message").val("");
				});
				$("#message").keyup(function(e){
					if (e.keyCode == 13){
						sendMessage("send", $("#message").val());
						$("#message").val("");
					}
				});
			});
		</script>
	</head>
	<body>
		<div id="message_box" style="width:500px;height:300px;overflow:scroll;font-size:12px">
			<ul></ul>
		</div>
		<input type="text" id="message" name="message" />
		<input type="button" value="보내기" id="send_btn" name="send_btn" /><br />
	</body>
</html>
일단 Channel클래스를 쓰려면 <script src="/_ah/channel/jsapi"></script>를 include해야해요. 그리고, new goog.appengine.Channel생성부분을 유심히 보면 함수로 onopen, onmessage, onerror, onclose를 등록할 수 있어요. 메세지를 받으면 onmessage가 호출이 되니 여기서 처리하면 됨 ㅇㅇ 보내는 것은 아까 java에서 만들어 놓은 url을 호출하면 됨. 끗~

예제주소는 여기
http://mudchobo.appspot.com/apps/channeltest/test

소스파일...귀찮아서 그냥....통째로.....-_-



ps. 한글이 깨지길래 보낼 때 인코딩하고, 다시 받을 때 url인코딩해서 보내고 받은 걸 푸는 방식으로 했더니 되네요. 

 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon 레몬에이드 2011.01.31 14:05 신고  댓글주소  수정/삭제  댓글쓰기

    음... 역쉬 만능! 못하시능게 없어! +ㅁ+

  2. JIN32 2011.03.09 15:47  댓글주소  수정/삭제  댓글쓰기

    죄송하지만 한가지 여쭤볼께요.
    로컬에서 테스트할때

    <script src="/_ah/channel/jsapi"></script>

    이 부분에요.

    com.google.appengine.api.channel.dev.LocalChannelFailureException: Channel for application key null not found.

    이런 오류가 발생되는데...
    혹시 해결방법 알고 계시는지 궁금해서 댓글 남겨봅니다.

    암튼 좋은글 잘 보고 갑니다.
    감사합니다. ^^

  3. Jin 2011.09.06 00:57  댓글주소  수정/삭제  댓글쓰기

    우와 전부터 앱엔진으로 채팅기능 구현하고싶었는데 channel api가 있는지 처음알았네요 좋은정보 감사합니다^^

  4. gslee 2011.09.22 08:41  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~
    구글앱엔진 java 를 공부하고있는데요안드로이드랑연결시켜서 간단하게 방명록처럼만드려고 하는데 한글이 전부깨지내요 ㅠ
    해결방법을 아시면 저에게 도움좀 부탁드립니다^^
    skyyy80@gmail.com

  5. gslee 2011.09.22 08:41  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~
    구글앱엔진 java 를 공부하고있는데요안드로이드랑연결시켜서 간단하게 방명록처럼만드려고 하는데 한글이 전부깨지내요 ㅠ
    해결방법을 아시면 저에게 도움좀 부탁드립니다^^
    skyyy80@gmail.com