001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.apache.mina.example.chat;
021:
022: import java.util.Collections;
023: import java.util.HashSet;
024: import java.util.Set;
025:
026: import org.apache.mina.common.IoHandler;
027: import org.apache.mina.common.IoHandlerAdapter;
028: import org.apache.mina.common.IoSession;
029: import org.apache.mina.filter.logging.MdcInjectionFilter;
030: import org.slf4j.Logger;
031: import org.slf4j.LoggerFactory;
032:
033: /**
034: * {@link IoHandler} implementation of a simple chat server protocol.
035: *
036: * @author The Apache MINA Project (dev@mina.apache.org)
037: * @version $Rev$, $Date$
038: */
039: public class ChatProtocolHandler extends IoHandlerAdapter {
040: private final Logger logger = LoggerFactory.getLogger(getClass());
041:
042: private final Set<IoSession> sessions = Collections
043: .synchronizedSet(new HashSet<IoSession>());
044:
045: private final Set<String> users = Collections
046: .synchronizedSet(new HashSet<String>());
047:
048: @Override
049: public void exceptionCaught(IoSession session, Throwable cause) {
050: logger.warn("Unexpected exception.", cause);
051: // Close connection when unexpected exception is caught.
052: session.close();
053: }
054:
055: @Override
056: public void messageReceived(IoSession session, Object message) {
057: Logger log = LoggerFactory.getLogger(ChatProtocolHandler.class);
058: log.info("received: " + message);
059: String theMessage = (String) message;
060: String[] result = theMessage.split(" ", 2);
061: String theCommand = result[0];
062:
063: try {
064:
065: ChatCommand command = ChatCommand.valueOf(theCommand);
066: String user = (String) session.getAttribute("user");
067:
068: switch (command.toInt()) {
069:
070: case ChatCommand.QUIT:
071: session.write("QUIT OK");
072: session.close();
073: break;
074: case ChatCommand.LOGIN:
075:
076: if (user != null) {
077: session.write("LOGIN ERROR user " + user
078: + " already logged in.");
079: return;
080: }
081:
082: if (result.length == 2) {
083: user = result[1];
084: } else {
085: session.write("LOGIN ERROR invalid login command.");
086: return;
087: }
088:
089: // check if the username is already used
090: if (users.contains(user)) {
091: session.write("LOGIN ERROR the name " + user
092: + " is already used.");
093: return;
094: }
095:
096: sessions.add(session);
097: session.setAttribute("user", user);
098: MdcInjectionFilter.setProperty(session, "user", user);
099:
100: // Allow all users
101: users.add(user);
102: session.write("LOGIN OK");
103: broadcast("The user " + user
104: + " has joined the chat session.");
105: break;
106:
107: case ChatCommand.BROADCAST:
108:
109: if (result.length == 2) {
110: broadcast(user + ": " + result[1]);
111: }
112: break;
113: default:
114: logger.info("Unhandled command: " + command);
115: break;
116: }
117:
118: } catch (IllegalArgumentException e) {
119: logger.debug("Illegal argument", e);
120: }
121: }
122:
123: public void broadcast(String message) {
124: synchronized (sessions) {
125: for (IoSession session : sessions) {
126: if (session.isConnected()) {
127: session.write("BROADCAST OK " + message);
128: }
129: }
130: }
131: }
132:
133: @Override
134: public void sessionClosed(IoSession session) throws Exception {
135: String user = (String) session.getAttribute("user");
136: users.remove(user);
137: sessions.remove(session);
138: broadcast("The user " + user + " has left the chat session.");
139: }
140:
141: public boolean isChatUser(String name) {
142: return users.contains(name);
143: }
144:
145: public int getNumberOfUsers() {
146: return users.size();
147: }
148:
149: public void kick(String name) {
150: synchronized (sessions) {
151: for (IoSession session : sessions) {
152: if (name.equals(session.getAttribute("user"))) {
153: session.close();
154: break;
155: }
156: }
157: }
158: }
159: }
|