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