Skip to content

Instantly share code, notes, and snippets.

@vvakame
Last active December 11, 2015 10:09
Show Gist options
  • Save vvakame/4584906 to your computer and use it in GitHub Desktop.
Save vvakame/4584906 to your computer and use it in GitHub Desktop.
GAE/J のChannel APIを試した時のサンプル。 一意のIDからTokenを生成して利用する。送信する時は一意のIDに対して送信を行うのでTokenなどを知っている必要はない。 まとめると、User KindのKeyのIDなりNameなりに対して適当にメッセージを送りつけてやれば相手が受信可能であれば受け取る。といった感じみたい。たぶん。
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>vvakame-hrd</application>
<version>channel-api-sample</version>
<static-files>
<include path="/**.*" />
</static-files>
<precompilation-enabled>true</precompilation-enabled>
<inbound-services>
<service>channel_presence</service>
</inbound-services>
<system-properties>
<property name="slim3.hotReloading" value="true" />
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties" />
</system-properties>
<sessions-enabled>false</sessions-enabled>
<threadsafe>true</threadsafe>
</appengine-web-app>
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;
import org.slim3.repackaged.org.json.JSONObject;
import org.slim3.util.StringUtil;
import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class ChannelController extends Controller {
@Override
protected Navigation run() throws Exception {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user == null) {
String loginURL = userService.createLoginURL("/");
JSONObject jsonObject = new JSONObject();
jsonObject.put("redirectTo", loginURL);
Writer writer = new PrintWriter(response.getOutputStream());
writer.write(jsonObject.toString());
writer.flush();
return null;
}
{
ChannelUser channelUser = new ChannelUser();
channelUser.setKey(Datastore.createKey(ChannelUser.class,
user.getUserId()));
channelUser.setUser(user);
Datastore.put(channelUser);
}
if (isGet()) {
String token = getToken(user.getUserId());
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", user.getUserId());
jsonObject.put("token", token);
Writer writer = new PrintWriter(response.getOutputStream());
writer.write(jsonObject.toString());
writer.flush();
} else {
String message = asString("message");
if (StringUtil.isEmpty(message)) {
return null;
}
List<ChannelUser> list = Datastore.query(ChannelUser.class)
.asList();
for (ChannelUser channelUser : list) {
sendUpdateToUser(channelUser.getKey().getName(), message);
}
response.getOutputStream().write("{}".getBytes());
}
return null;
}
void sendUpdateToUser(String userId, String message) {
ChannelService channelService = ChannelServiceFactory
.getChannelService();
channelService.sendMessage(new ChannelMessage(userId, message));
}
String getToken(String userId) {
ChannelService channelService = ChannelServiceFactory
.getChannelService();
String token = channelService.createChannel(userId);
return token;
}
}
import org.slim3.datastore.Attribute;
import org.slim3.datastore.Model;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.users.User;
@Model
public class ChannelUser {
@Attribute(primaryKey = true)
Key key;
User user;
/**
* @return the key
*/
public Key getKey() {
return key;
}
/**
* @param key
* the key to set
*/
public void setKey(Key key) {
this.key = key;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @param user
* the user to set
*/
public void setUser(User user) {
this.user = user;
}
}
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="/_ah/channel/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<title>Channel API</title>
<script type="text/javascript">
var socket;
$(document).ready(function () {
$.ajax({
type:"GET",
url:"/channel",
contentType:"application/json",
dataType:"json",
data:{},
success:function (data) {
console.log(data);
if (data.redirectTo) {
window.location = data.redirectTo;
return;
}
var channel = new goog.appengine.Channel(data.token);
socket = channel.open();
socket.onopen = function () {
addText("接続が開始されました。データを送信できます");
};
socket.onerror = function () {
addText("サーバでエラー!");
};
socket.onclose = function () {
addText("接続が正常に終了しました");
};
socket.onmessage = function (data) {
console.log(data);
addText(data.data);
};
addText("あなたのuserIdは" + data.userId + "です。");
}
});
$("#send").on("click", function () {
$.ajax({
type:"POST",
url:"/channel",
data:{
message:$("#message").val()
},
success:function (data) {
console.log(data);
}
});
});
});
function addText(text) {
console.log(text);
$("<div>").text(text).appendTo($("#content"));
}
</script>
</head>
<body>
<div id="content">
</div>
<input id="message" type="text" value="">
<input id="send" type="button" value="データを送信">
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment