1
2
3
4 package org.cometd.demo;
5
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.Map;
9 import java.util.concurrent.ConcurrentHashMap;
10 import java.util.concurrent.ConcurrentMap;
11
12 import org.cometd.Bayeux;
13 import org.cometd.Channel;
14 import org.cometd.Client;
15 import org.cometd.RemoveListener;
16 import org.mortbay.cometd.BayeuxService;
17 import org.mortbay.log.Log;
18
19 public class ChatService extends BayeuxService
20 {
21
22
23
24 private final ConcurrentMap<String, Map<String, String>> _members = new ConcurrentHashMap<String, Map<String, String>>();
25
26 public ChatService(Bayeux bayeux)
27 {
28 super(bayeux, "chat");
29 subscribe("/chat/**", "trackMembers");
30 subscribe("/service/privatechat", "privateChat");
31 }
32
33 public void trackMembers(final Client joiner, final String channelName, Map<String, Object> data, final String messageId)
34 {
35 if (Boolean.TRUE.equals(data.get("join")))
36 {
37 Map<String, String> membersMap = _members.get(channelName);
38 if (membersMap == null)
39 {
40 Map<String, String> newMembersMap = new ConcurrentHashMap<String, String>();
41 membersMap = _members.putIfAbsent(channelName, newMembersMap);
42 if (membersMap == null) membersMap = newMembersMap;
43 }
44
45 final Map<String, String> members = membersMap;
46 final String userName = (String)data.get("user");
47 members.put(userName, joiner.getId());
48 joiner.addListener(new RemoveListener()
49 {
50 public void removed(String clientId, boolean timeout)
51 {
52 members.values().remove(clientId);
53 Log.info("members: " + members);
54
55 Channel channel = getBayeux().getChannel(channelName, false);
56 if (channel != null) channel.publish(getClient(), members.keySet(), messageId);
57 }
58 });
59
60 Log.info("Members: " + members);
61
62 getBayeux().getChannel(channelName, false).publish(getClient(), members.keySet(), messageId);
63 }
64 }
65
66 public void privateChat(Client source, String channel, Map<String, Object> data, String messageId)
67 {
68 String roomName = (String)data.get("room");
69 Map<String, String> membersMap = _members.get(roomName);
70 String[] peerNames = ((String)data.get("peer")).split(",");
71 ArrayList<Client> peers = new ArrayList<Client>(peerNames.length);
72
73 for (String peerName : peerNames)
74 {
75 String peerId = membersMap.get(peerName);
76 if (peerId!=null)
77 {
78 Client peer = getBayeux().getClient(peerId);
79 if (peer!=null)
80 peers.add(peer);
81 }
82 }
83
84 if (peers.size()>0)
85 {
86 Map<String, Object> message = new HashMap<String, Object>();
87 message.put("chat", data.get("chat"));
88 message.put("user", data.get("user"));
89 message.put("scope", "private");
90 for (int i = 0; i < peers.size(); ++i) peers.get(i).deliver(source, roomName, message, messageId);
91 source.deliver(getClient(), roomName, message, messageId);
92 }
93 else if (!"silent".equals(data.get("peer")))
94 {
95 Map<String, Object> message = new HashMap<String, Object>();
96 message.put("chat", "Unknown user(s): "+data.get("peer"));
97 message.put("user", "SERVER");
98 message.put("scope", "error");
99 source.deliver(source, roomName, message, messageId);
100 }
101 }
102 }
103