/**
*
*/
package org.cometd.demo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.cometd.Bayeux;
import org.cometd.Channel;
import org.cometd.Client;
import org.cometd.RemoveListener;
import org.mortbay.cometd.BayeuxService;
public class ChatService extends BayeuxService
{
/**
* A map(channel, map(userName, clientId))
*/
private final ConcurrentMap<String, Map<String, String>> _members = new ConcurrentHashMap<String, Map<String, String>>();
public ChatService(Bayeux bayeux)
{
super(bayeux, "chat");
subscribe("/service/members", "handleMembership");
subscribe("/service/privatechat", "privateChat");
}
public void handleMembership(Client client, Map<String, Object> data)
{
String room = (String)data.get("room");
Map<String, String> roomMembers = _members.get(room);
if (roomMembers == null)
{
Map<String, String> newRoomMembers = new ConcurrentHashMap<String, String>();
roomMembers = _members.putIfAbsent(room, newRoomMembers);
if (roomMembers == null)
roomMembers = newRoomMembers;
}
final Map<String, String> members = roomMembers;
String userName = (String)data.get("user");
if (userName != null)
{
members.put(userName, client.getId());
client.addListener(new RemoveListener()
{
public void removed(String clientId, boolean timeout)
{
members.values().remove(clientId);
broadcastMembers(members.keySet());
}
});
}
broadcastMembers(members.keySet());
}
private void broadcastMembers(Set<String> members)
{
// Broadcast the new members list
Channel channel = getBayeux().getChannel("/chat/members", false);
if (channel != null)
channel.publish(getClient(), members, null);
}
public void privateChat(Client client, Map<String, Object> data)
{
String roomName = (String)data.get("room");
Map<String, String> membersMap = _members.get(roomName);
String[] peerNames = ((String)data.get("peer")).split(",");
ArrayList<Client> peers = new ArrayList<Client>(peerNames.length);
for (String peerName : peerNames)
{
String peerId = membersMap.get(peerName);
if (peerId!=null)
{
Client peer = getBayeux().getClient(peerId);
if (peer!=null)
peers.add(peer);
}
}
if (peers.size() > 0)
{
Map<String, Object> message = new HashMap<String, Object>();
message.put("chat", data.get("chat"));
message.put("user", data.get("user"));
message.put("scope", "private");
for (Client peer : peers)
peer.deliver(client, roomName, message, null);
client.deliver(getClient(), roomName, message, null);
}
}
}