1. [代码]Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
import
java.net.InetSocketAddress;
import
org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import
org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import
org.apache.mina.filter.codec.ProtocolCodecFilter;
import
org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import
org.apache.mina.filter.logging.LoggingFilter;
import
org.apache.mina.filter.logging.MdcInjectionFilter;
import
org.apache.mina.filter.ssl.SslFilter;
import
org.apache.mina.transport.socket.nio.NioSocketAcceptor;
/**
* (<b>Entry point</b>) Chat server
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev$, $Date$
*/
public
class
Main {
/** Choose your favorite port number. */
private
static
final
int
PORT =
1234
;
/** Set this to true if you want to make the server SSL */
private
static
final
boolean
USE_SSL =
false
;
public
static
void
main(String[] args)
throws
Exception {
NioSocketAcceptor acceptor =
new
NioSocketAcceptor();
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
MdcInjectionFilter mdcInjectionFilter =
new
MdcInjectionFilter();
chain.addLast(
"mdc"
, mdcInjectionFilter);
// Add SSL filter if SSL is enabled.
if
(USE_SSL) {
addSSLSupport(chain);
}
chain.addLast(
"codec"
,
new
ProtocolCodecFilter(
new
TextLineCodecFactory()));
addLogger(chain);
// Bind
acceptor.setHandler(
new
ChatProtocolHandler());
acceptor.bind(
new
InetSocketAddress(PORT));
System.out.println(
"Listening on port "
+ PORT);
}
private
static
void
addSSLSupport(DefaultIoFilterChainBuilder chain)
throws
Exception {
SslFilter sslFilter =
new
SslFilter(BogusSslContextFactory
.getInstance(
true
));
chain.addLast(
"sslFilter"
, sslFilter);
System.out.println(
"SSL ON"
);
}
private
static
void
addLogger(DefaultIoFilterChainBuilder chain)
throws
Exception {
chain.addLast(
"logger"
,
new
LoggingFilter());
System.out.println(
"Logging ON"
);
}
}
|
2. [代码]ChatCommand 跳至 [1] [2] [3] [全屏预览]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/**
* Encapsulates a chat command. Use {@link #valueOf(String)} to create an
* instance given a command string.
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev$, $Date$
*/
public
class
ChatCommand {
public
static
final
int
LOGIN =
0
;
public
static
final
int
QUIT =
1
;
public
static
final
int
BROADCAST =
2
;
private
final
int
num;
private
ChatCommand(
int
num) {
this
.num = num;
}
public
int
toInt() {
return
num;
}
public
static
ChatCommand valueOf(String s) {
s = s.toUpperCase();
if
(
"LOGIN"
.equals(s)) {
return
new
ChatCommand(LOGIN);
}
if
(
"QUIT"
.equals(s)) {
return
new
ChatCommand(QUIT);
}
if
(
"BROADCAST"
.equals(s)) {
return
new
ChatCommand(BROADCAST);
}
throw
new
IllegalArgumentException(
"Unrecognized command: "
+ s);
}
}
|
3. [代码]ChatProtocolHandler 跳至 [1] [2] [3] [全屏预览]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
import
java.util.Collections;
import
java.util.HashSet;
import
java.util.Set;
import
org.apache.mina.core.service.IoHandler;
import
org.apache.mina.core.service.IoHandlerAdapter;
import
org.apache.mina.core.session.IoSession;
import
org.apache.mina.filter.logging.MdcInjectionFilter;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
/**
* {@link IoHandler} implementation of a simple chat server protocol.
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev$, $Date$
*/
public
class
ChatProtocolHandler
extends
IoHandlerAdapter {
private
final
Logger logger = LoggerFactory.getLogger(getClass());
private
final
Set<IoSession> sessions = Collections
.synchronizedSet(
new
HashSet<IoSession>());
private
final
Set<String> users = Collections
.synchronizedSet(
new
HashSet<String>());
@Override
public
void
exceptionCaught(IoSession session, Throwable cause) {
logger.warn(
"Unexpected exception."
, cause);
// Close connection when unexpected exception is caught.
session.close(
true
);
}
@Override
public
void
messageReceived(IoSession session, Object message) {
Logger log = LoggerFactory.getLogger(ChatProtocolHandler.
class
);
log.info(
"received: "
+ message);
String theMessage = (String) message;
String[] result = theMessage.split(
" "
,
2
);
String theCommand = result[
0
];
try
{
ChatCommand command = ChatCommand.valueOf(theCommand);
String user = (String) session.getAttribute(
"user"
);
switch
(command.toInt()) {
case
ChatCommand.QUIT:
session.write(
"QUIT OK"
);
session.close(
true
);
break
;
case
ChatCommand.LOGIN:
if
(user !=
null
) {
session.write(
"LOGIN ERROR user "
+ user
+
" already logged in."
);
return
;
}
if
(result.length ==
2
) {
user = result[
1
];
}
else
{
session.write(
"LOGIN ERROR invalid login command."
);
return
;
}
// check if the username is already used
if
(users.contains(user)) {
session.write(
"LOGIN ERROR the name "
+ user
+
" is already used."
);
return
;
}
sessions.add(session);
session.setAttribute(
"user"
, user);
MdcInjectionFilter.setProperty(session,
"user"
, user);
// Allow all users
users.add(user);
session.write(
"LOGIN OK"
);
broadcast(
"The user "
+ user +
" has joined the chat session."
);
break
;
case
ChatCommand.BROADCAST:
if
(result.length ==
2
) {
broadcast(user +
": "
+ result[
1
]);
}
break
;
default
:
logger.info(
"Unhandled command: "
+ command);
break
;
}
}
catch
(IllegalArgumentException e) {
logger.debug(
"Illegal argument"
, e);
}
}
public
void
broadcast(String message) {
synchronized
(sessions) {
for
(IoSession session : sessions) {
if
(session.isConnected()) {
session.write(
"BROADCAST OK "
+ message);
}
}
}
}
@Override
public
void
sessionClosed(IoSession session)
throws
Exception {
String user = (String) session.getAttribute(
"user"
);
users.remove(user);
sessions.remove(session);
broadcast(
"The user "
+ user +
" has left the chat session."
);
}
public
boolean
isChatUser(String name) {
return
users.contains(name);
}
public
int
getNumberOfUsers() {
return
users.size();
}
public
void
kick(String name) {
synchronized
(sessions) {
for
(IoSession session : sessions) {
if
(name.equals(session.getAttribute(
"user"
))) {
session.close(
true
);
break
;
}
}
}
}
}
|