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