Mina是Apache下的一個網絡應用程序框架,用來幫助用戶簡單地開發高性能和高可擴展性的網絡應用程序。它提供了一個經過Java NIO在不一樣的傳輸協議上抽象的事件驅動的異步API,例如TCP/IP和UDP/IP。 html
還沒了解原理以前,咱們先從官網例子改寫一下,從實踐開始。我記得入行前有個前輩說過,學習任何新技術,不要先急着瞭解其原理,先找個例子實踐一下。我以爲至關正確,由於沒有誰在學習自行車前,是先把自行車運行原理弄清楚的。 java
依賴:jdk1.7 apache
開發環境:ideaIU-14.1.4 緩存
測試環境:win7 網絡
創建maven工程MinaDemo,在pom.xml配置文件添加必要的依賴: session
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<
modelVersion
>4.0.0</
modelVersion
>
<
groupId
>MinaDemo</
groupId
>
<
artifactId
>MinaDemo</
artifactId
>
<
version
>1.0-SNAPSHOT</
version
>
<
dependencies
>
<
dependency
>
<
groupId
>org.apache.mina</
groupId
>
<
artifactId
>mina-core</
artifactId
>
<
version
>2.0.9</
version
>
</
dependency
>
</
dependencies
>
</
project
>
|
TimeServer.java類: 框架
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
|
package
com.mangocool.mina;
import
java.io.IOException;
import
java.net.InetSocketAddress;
import
java.nio.charset.Charset;
import
org.apache.mina.core.service.IoAcceptor;
import
org.apache.mina.core.session.IdleStatus;
import
org.apache.mina.filter.codec.ProtocolCodecFilter;
import
org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;
import
org.apache.mina.filter.logging.LoggingFilter;
import
org.apache.mina.transport.socket.nio.NioSocketAcceptor;
/**
* Created by MANGOCOOL on 2015/10/20.
*/
public
class
TimeServer {
private
static
final
int
PORT =
9123
;
public
static
void
main(String[] args)
throws
IOException
{
// 建立服務監聽器,6是IoProcessor的線程數
IoAcceptor acceptor =
new
NioSocketAcceptor(
6
);
// 增長日誌過濾器
acceptor.getFilterChain().addLast(
"logger"
,
new
LoggingFilter());
// 增長編碼過濾器,統一編碼UTF-8
acceptor.getFilterChain().addLast(
"codec"
,
new
ProtocolCodecFilter(
new
PrefixedStringCodecFactory(Charset.forName(
"UTF-8"
))));
// 設置服務端邏輯處理器
acceptor.setHandler(
new
TimeServerHandler());
// 設置讀緩存大小
acceptor.getSessionConfig().setReadBufferSize(
2048
);
// 設置指定類型的空閒時間,空閒時間超過這個值將觸發sessionIdle方法
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
10
);
// 綁定端口
acceptor.bind(
new
InetSocketAddress(PORT));
}
}
|
TimeServerHandler.java類: 異步
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
|
package
com.mangocool.mina;
import
java.util.Date;
import
org.apache.mina.core.service.IoHandler;
import
org.apache.mina.core.session.IdleStatus;
import
org.apache.mina.core.session.IoSession;
/**
* Created by MANGOCOOL on 2015/10/20.
*/
public
class
TimeServerHandler
implements
IoHandler {
@Override
public
void
exceptionCaught(IoSession session, Throwable throwable)
throws
Exception
{
throwable.printStackTrace();
}
@Override
public
void
messageReceived(IoSession session, Object message)
throws
Exception
{
String str = message.toString();
System.out.println(
"server端接收到的消息:"
+ str);
if
(str.trim().equalsIgnoreCase(
"exit"
))
{
session.close(
true
);
return
;
}
Date date =
new
Date();
session.write(date.toString());
}
@Override
public
void
messageSent(IoSession session, Object message)
throws
Exception
{
System.out.println(
"server端發送信息:"
+ message.toString());
}
public
void
inputClosed(IoSession session)
throws
Exception
{
System.out.println(
"server端:"
+ session.getId() +
" 關閉輸入"
);
}
@Override
public
void
sessionClosed(IoSession session)
throws
Exception
{
System.out.println(
"server端IP:"
+ session.getRemoteAddress().toString() +
" 關閉鏈接"
);
System.exit(
0
);
}
@Override
public
void
sessionCreated(IoSession session)
throws
Exception
{
System.out.println(
"server端IP:"
+ session.getRemoteAddress().toString() +
" 建立鏈接"
);
}
@Override
public
void
sessionIdle(IoSession session, IdleStatus status)
throws
Exception
{
System.out.println(
"server端閒置鏈接:會話 "
+ session.getId() +
" 被觸發 "
+ session.getIdleCount(status) +
" 次"
);
}
@Override
public
void
sessionOpened(IoSession session)
throws
Exception
{
System.out.println(
"server端打開鏈接"
);
}
}
|
public void exceptionCaught(IoSession session, Throwable cause) 當接口中其餘方法拋出異常未被捕獲時觸發此方法。
public void messageReceived(IoSession session, Object message) 當接收到客戶端的請求信息後觸發此方法。
public void messageSent(IoSession session, Object message) 當信息已經發送至客戶端後觸發此方法。
public void inputClosed(IoSession session) 當信息接收被關閉輸入時觸發次方法。
public void sessionClosed(IoSession session) 當鏈接被關閉時觸發,例如客戶端程序意外退出等。
public void sessionCreated(IoSession session) 當一個新客戶端鏈接後觸發此方法。
public void sessionIdle(IoSession session, IdleStatus status) 當鏈接空閒時觸發此方法。
public void sessionOpened(IoSession session) 當鏈接後打開時觸發此方法,通常此方法與 sessionCreated 會被同時觸發。 socket
本類實現的是IoHandler接口,因此覆蓋了IoHandler接口的全部方法。這裏能夠繼承抽象類IoHandlerAdapter,根據業務的須要實現須要的方法。maven
TimeClient.java類:
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
|
package
com.mangocool.mina;
import
org.apache.mina.core.future.ConnectFuture;
import
org.apache.mina.core.service.IoConnector;
import
org.apache.mina.core.session.IoSession;
import
org.apache.mina.filter.codec.ProtocolCodecFilter;
import
org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;
import
org.apache.mina.filter.logging.LoggingFilter;
import
org.apache.mina.transport.socket.nio.NioSocketConnector;
import
java.net.InetSocketAddress;
import
java.nio.charset.Charset;
import
java.util.Scanner;
/**
* Created by MANGOCOOL on 2015/10/20.
*/
public
class
TimeClient {
private
static
final
int
PORT =
9123
;
public
static
void
main(String[] args)
{
// 建立客戶端鏈接
IoConnector connector =
new
NioSocketConnector();
// 增長日誌過濾器
connector.getFilterChain().addLast(
"logger"
,
new
LoggingFilter());
// 增長編碼過濾器,統一編碼UTF-8
connector.getFilterChain().addLast(
"codec"
,
new
ProtocolCodecFilter(
new
PrefixedStringCodecFactory(Charset.forName(
"UTF-8"
))));
// 設置客戶端邏輯處理器
connector.setHandler(
new
TimeClientHandler());
// 鏈接
ConnectFuture connectFuture = connector.connect(
new
InetSocketAddress(
"localhost"
, PORT));
// 等待創建鏈接
connectFuture.awaitUninterruptibly();
// 獲取鏈接會話
IoSession session = connectFuture.getSession();
// 等待輸入
Scanner sc =
new
Scanner(System.in);
System.out.println(
"客戶端內容輸入:"
);
boolean
exit =
false
;
// 輸入exit,退出系統
while
(!exit)
{
String str = sc.next();
session.write(str);
if
(str.equalsIgnoreCase(
"exit"
))
{
exit =
true
;
session.close(
true
);
}
}
}
}
|
TimeClientHandler.java類:
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
|
package
com.mangocool.mina;
import
org.apache.mina.core.service.IoHandler;
import
org.apache.mina.core.session.IdleStatus;
import
org.apache.mina.core.session.IoSession;
/**
* Created by MANGOCOOL on 2015/10/20.
*/
public
class
TimeClientHandler
implements
IoHandler {
@Override
public
void
exceptionCaught(IoSession session, Throwable throwable)
throws
Exception
{
throwable.printStackTrace();
}
@Override
public
void
messageReceived(IoSession session, Object message)
throws
Exception
{
System.out.println(
"client端接收信息:"
+ message.toString());
}
@Override
public
void
messageSent(IoSession session, Object message)
throws
Exception
{
System.out.println(
"client端發送信息:"
+ message.toString());
}
public
void
inputClosed(IoSession session)
throws
Exception
{
System.out.println(
"client端:"
+ session.getId() +
" 關閉輸入"
);
}
@Override
public
void
sessionClosed(IoSession session)
throws
Exception
{
System.out.println(
"client端與:"
+ session.getRemoteAddress().toString() +
" 關閉鏈接"
);
System.exit(
0
);
}
@Override
public
void
sessionCreated(IoSession session)
throws
Exception
{
System.out.println(
"client端與:"
+ session.getRemoteAddress().toString() +
" 創建鏈接"
);
}
@Override
public
void
sessionIdle(IoSession session, IdleStatus status)
throws
Exception
{
System.out.println(
"client端閒置鏈接:會話 "
+ session.getId() +
" 被觸發 "
+ session.getIdleCount(status) +
" 次"
);
}
@Override
public
void
sessionOpened(IoSession session)
throws
Exception
{
System.out.println(
"client端打開鏈接"
);
}
}
|
自定義過濾器MyFilter.java類:
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
|
package
com.mangocool.mina;
import
org.apache.mina.core.filterchain.IoFilter;
import
org.apache.mina.core.filterchain.IoFilterChain;
import
org.apache.mina.core.session.IdleStatus;
import
org.apache.mina.core.session.IoSession;
import
org.apache.mina.core.write.WriteRequest;
/**
* Created by MANGOCOOL on 2015/10/27.
*/
public
class
MyFilter
implements
IoFilter {
@Override
public
void
init()
throws
Exception {
System.out.println(
"MyFilter init..."
);
}
@Override
public
void
destroy()
throws
Exception {
System.out.println(
"MyFilter destroy..."
);
}
@Override
public
void
onPreAdd(IoFilterChain ioFilterChain, String s, NextFilter nextFilter)
throws
Exception {
System.out.println(
"MyFilter onPreAdd..."
);
}
@Override
public
void
onPostAdd(IoFilterChain ioFilterChain, String s, NextFilter nextFilter)
throws
Exception {
System.out.println(
"MyFilter onPostAdd..."
);
}
@Override
public
void
onPreRemove(IoFilterChain ioFilterChain, String s, NextFilter nextFilter)
throws
Exception {
System.out.println(
"MyFilter onPreRemove..."
);
}
@Override
public
void
onPostRemove(IoFilterChain ioFilterChain, String s, NextFilter nextFilter)
throws
Exception {
System.out.println(
"MyFilter onPostRemove..."
);
}
@Override
public
void
sessionCreated(NextFilter nextFilter, IoSession ioSession)
throws
Exception {
System.out.println(
"MyFilter sessionCreated..."
);
}
@Override
public
void
sessionOpened(NextFilter nextFilter, IoSession ioSession)
throws
Exception {
System.out.println(
"MyFilter sessionOpened..."
);
}
@Override
public
void
sessionClosed(NextFilter nextFilter, IoSession ioSession)
throws
Exception {
System.out.println(
"MyFilter sessionClosed..."
);
}
@Override
public
void
sessionIdle(NextFilter nextFilter, IoSession ioSession, IdleStatus idleStatus)
throws
Exception {
System.out.println(
"MyFilter sessionIdle..."
);
}
@Override
public
void
exceptionCaught(NextFilter nextFilter, IoSession ioSession, Throwable throwable)
throws
Exception {
System.out.println(
"MyFilter exceptionCaught..."
);
}
@Override
public
void
inputClosed(NextFilter nextFilter, IoSession ioSession)
throws
Exception {
System.out.println(
"MyFilter inputClosed..."
);
}
@Override
public
void
messageReceived(NextFilter nextFilter, IoSession ioSession, Object o)
throws
Exception {
System.out.println(
"MyFilter messageReceived..."
);
}
@Override
public
void
messageSent(NextFilter nextFilter, IoSession ioSession, WriteRequest writeRequest)
throws
Exception {
System.out.println(
"MyFilter messageSent..."
);
}
@Override
public
void
filterClose(NextFilter nextFilter, IoSession ioSession)
throws
Exception {
System.out.println(
"MyFilter filterClose..."
);
}
@Override
public
void
filterWrite(NextFilter nextFilter, IoSession ioSession, WriteRequest writeRequest)
throws
Exception {
System.out.println(
"MyFilter filterWrite..."
);
}
}
|
MyFilter能夠跟日誌過濾器和編碼過濾器同樣,被添加到客戶端和服務端,對應方法的實現,能夠根據業務作對應的處理。
MINA還提供了一個IoFilterAdapter類,咱們編寫本身的Filter時,也能夠擴展IoFilterAdapter,根據業務實現需要的方法便可,不用直接實現IoFilter接口。
測試,啓動服務端TimeServer、客戶端TimeClient開始測試,結果以下:
http://mangocool.com/1445415396806.html