View Javadoc

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.Set;
10  import java.util.concurrent.ConcurrentHashMap;
11  import java.util.concurrent.ConcurrentMap;
12  
13  import org.cometd.Bayeux;
14  import org.cometd.Channel;
15  import org.cometd.Client;
16  import org.cometd.RemoveListener;
17  import org.mortbay.cometd.BayeuxService;
18  
19  public class ChatService extends BayeuxService
20  {
21      /**
22       * A map(channel, map(userName, clientId))
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("/service/members", "handleMembership");
30          subscribe("/service/privatechat", "privateChat");
31      }
32  
33      public void handleMembership(Client client, Map<String, Object> data)
34      {
35          String room = (String)data.get("room");
36          Map<String, String> roomMembers = _members.get(room);
37          if (roomMembers == null)
38          {
39              Map<String, String> newRoomMembers = new ConcurrentHashMap<String, String>();
40              roomMembers = _members.putIfAbsent(room, newRoomMembers);
41              if (roomMembers == null)
42                  roomMembers = newRoomMembers;
43          }
44          final Map<String, String> members = roomMembers;
45          String userName = (String)data.get("user");
46          if (userName != null)
47          {
48              members.put(userName, client.getId());
49              client.addListener(new RemoveListener()
50              {
51                  public void removed(String clientId, boolean timeout)
52                  {
53                      members.values().remove(clientId);
54                      broadcastMembers(members.keySet());
55                  }
56              });
57          }
58          broadcastMembers(members.keySet());
59      }
60  
61      private void broadcastMembers(Set<String> members)
62      {
63          // Broadcast the new members list
64          Channel channel = getBayeux().getChannel("/chat/members", false);
65          if (channel != null)
66              channel.publish(getClient(), members, null);
67      }
68  
69      public void privateChat(Client client, Map<String, Object> data)
70      {
71          String roomName = (String)data.get("room");
72          Map<String, String> membersMap = _members.get(roomName);
73          String[] peerNames = ((String)data.get("peer")).split(",");
74          ArrayList<Client> peers = new ArrayList<Client>(peerNames.length);
75  
76          for (String peerName : peerNames)
77          {
78              String peerId = membersMap.get(peerName);
79              if (peerId!=null)
80              {
81                  Client peer = getBayeux().getClient(peerId);
82                  if (peer!=null)
83                      peers.add(peer);
84              }
85          }
86  
87          if (peers.size() > 0)
88          {
89              Map<String, Object> message = new HashMap<String, Object>();
90              message.put("chat", data.get("chat"));
91              message.put("user", data.get("user"));
92              message.put("scope", "private");
93              for (Client peer : peers)
94                  peer.deliver(client, roomName, message, null);
95              client.deliver(getClient(), roomName, message, null);
96          }
97      }
98  }