最近流行omegle,我也做了一个:
地址:http://hdc1112.appspot.com/client/client.html
核心代码:
package hust.ning;
import hust.ning.jdo.DAO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
public class ChatApp {
private static final Logger log = Logger.getLogger(ChatApp.class.getName());
private static ChatApp instance = null;
private ChatApp (){
// new Timer().schedule(new TimerTask(){
// @Override
// public void run() {
// checkTimeOut();
// }
// }, 60*1000,60*1000);//60s,不准我用Timer,我在adduser达到1000的时候check。
}
private void checkTimeOut()
{
log.info("checkTimeOut");
for(String k :activity.keySet())
{
if (!activity.get(k))
logout(k);
else
activity.put(k, false);
}
}
public static ChatApp getInstance()
{
if (instance==null)
instance=new ChatApp();
return instance;
}
private static int i = DAO.getUserCount();
private String genUUID()
{
return UUID.randomUUID().toString()+"_U"+i++;
}
public int getUserCount()
{
return i;
}
public int getCurrentUserCount()
{
if (singleUser==null)
return p2pmap.size();
else
return p2pmap.size()+1;
}
private Map<String,String> p2pmap = new HashMap<String, String>();
/**
* UserID -> content的map.
*/
private Map<String,List<String>> contents =new HashMap<String, List<String>>();
private Map<String ,Integer> counter = new HashMap<String, Integer>();//用于超时管理
private Map<String ,Boolean> activity = new HashMap<String, Boolean>();//用于超时管理。
private String singleUser;
public String getSingleUser ()
{
return singleUser;
}
public synchronized String login()
{
String id = this.genUUID();
counter.put(id, 0);
activity.put(id, true);
log.info("USER LOGIN:"+id);
DAO.saveChat(id, "SYSTEM:LOGIN");
if (null == singleUser)
{
singleUser=id;
return id;
}
log.info("PUT user to map :"+id +"<->"+ singleUser);
p2pmap.put(id, singleUser);
p2pmap.put(singleUser, id);
singleUser=null;
if (i%1024==0)
checkTimeOut();
return id;
}
public /*synchronized */void addChat(String uid,String content)
{
if (!p2pmap.containsKey(uid))
return ;//one of the peer is offline.
counter.put(uid, 0);//清零。
log.info(""+uid+":"+content);
DAO.saveChat(uid, content);
if (!contents.containsKey(uid))
contents.put(uid, new ArrayList<String>());
contents.get(uid).add(content);
}
public /*synchronized */List <String> getChat(String uid){
if (!activity.containsKey(uid))
return null;//null表示已经logout.
activity.put(uid, true);
int x = counter.get(uid);
if (x>20)//如果收到100个getNotification而没有一个addChat(),认为用户断线。
{
logout(uid);
return null;
}
counter.put(uid, x+1);
if (!p2pmap.containsKey(uid))
return null;//one of the peer is offline.
String peer= p2pmap.get(uid);
List <String >rst = contents.get(peer);
if (rst==null)
rst= new ArrayList<String>();
// log.info(":::"+rst);
contents.remove(peer);
return rst;
}
public void logout(String uid)
{
if (null!=p2pmap.get(uid))
logout2(p2pmap.get(uid));
logout2(uid);
}
private void logout2(String uid)
{
log.info("USER LOGOUT:"+uid );
if (uid==null)
return ;
DAO.saveChat(uid, "SYSTEM:LOGOUT");
if (uid.equals(singleUser))
singleUser=null;
p2pmap.remove(uid);
counter.remove(uid);
contents.remove(uid);
activity.remove(uid);
}
}
欢迎讨论。
GAE 没法支持comet,
不过现在了解到comet这样的技术,以后做类似项目的时候可以用了。