View Javadoc

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