1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.example.chat;
21
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Set;
25
26 import org.apache.mina.core.service.IoHandler;
27 import org.apache.mina.core.service.IoHandlerAdapter;
28 import org.apache.mina.core.session.IoSession;
29 import org.apache.mina.filter.logging.MdcInjectionFilter;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33
34
35
36
37
38
39 public class ChatProtocolHandler extends IoHandlerAdapter {
40 private final Logger logger = LoggerFactory.getLogger(getClass());
41
42 private final Set<IoSession> sessions = Collections
43 .synchronizedSet(new HashSet<IoSession>());
44
45 private final Set<String> users = Collections
46 .synchronizedSet(new HashSet<String>());
47
48 @Override
49 public void exceptionCaught(IoSession session, Throwable cause) {
50 logger.warn("Unexpected exception.", cause);
51
52 session.close();
53 }
54
55 @Override
56 public void messageReceived(IoSession session, Object message) {
57 Logger log = LoggerFactory.getLogger(ChatProtocolHandler.class);
58 log.info("received: " + message);
59 String theMessage = (String) message;
60 String[] result = theMessage.split(" ", 2);
61 String theCommand = result[0];
62
63 try {
64
65 ChatCommand command = ChatCommand.valueOf(theCommand);
66 String user = (String) session.getAttribute("user");
67
68 switch (command.toInt()) {
69
70 case ChatCommand.QUIT:
71 session.write("QUIT OK");
72 session.close();
73 break;
74 case ChatCommand.LOGIN:
75
76 if (user != null) {
77 session.write("LOGIN ERROR user " + user
78 + " already logged in.");
79 return;
80 }
81
82 if (result.length == 2) {
83 user = result[1];
84 } else {
85 session.write("LOGIN ERROR invalid login command.");
86 return;
87 }
88
89
90 if (users.contains(user)) {
91 session.write("LOGIN ERROR the name " + user
92 + " is already used.");
93 return;
94 }
95
96 sessions.add(session);
97 session.setAttribute("user", user);
98 MdcInjectionFilter.setProperty(session, "user", user);
99
100
101 users.add(user);
102 session.write("LOGIN OK");
103 broadcast("The user " + user + " has joined the chat session.");
104 break;
105
106 case ChatCommand.BROADCAST:
107
108 if (result.length == 2) {
109 broadcast(user + ": " + result[1]);
110 }
111 break;
112 default:
113 logger.info("Unhandled command: " + command);
114 break;
115 }
116
117 } catch (IllegalArgumentException e) {
118 logger.debug("Illegal argument", e);
119 }
120 }
121
122 public void broadcast(String message) {
123 synchronized (sessions) {
124 for (IoSession session : sessions) {
125 if (session.isConnected()) {
126 session.write("BROADCAST OK " + message);
127 }
128 }
129 }
130 }
131
132 @Override
133 public void sessionClosed(IoSession session) throws Exception {
134 String user = (String) session.getAttribute("user");
135 users.remove(user);
136 sessions.remove(session);
137 broadcast("The user " + user + " has left the chat session.");
138 }
139
140 public boolean isChatUser(String name) {
141 return users.contains(name);
142 }
143
144 public int getNumberOfUsers() {
145 return users.size();
146 }
147
148 public void kick(String name) {
149 synchronized (sessions) {
150 for (IoSession session : sessions) {
151 if (name.equals(session.getAttribute("user"))) {
152 session.close();
153 break;
154 }
155 }
156 }
157 }
158 }