通過mina框架來實(shí)現(xiàn)一個(gè)簡單的地圖實(shí)時(shí)位置共享,其實(shí)里面就相當(dāng)于做一個(gè)簡單的聊天室!客戶端A,說我在這里,客戶端B說我在那里,那么服務(wù)器就要存儲(chǔ)這兩個(gè)對(duì)象的會(huì)話,而兩個(gè)對(duì)象,成為Session!每一個(gè)客戶端添加進(jìn)來,則創(chuàng)建一個(gè)Session標(biāo)識(shí),保持與服務(wù)器的長連接!
Apache Mina是一個(gè)能夠幫助用戶開發(fā)高性能和高伸縮性網(wǎng)絡(luò)應(yīng)用程序的框架。它通過Java nio技術(shù)基于TCP/IP和UDP/IP協(xié)議提供了抽象的、事件驅(qū)動(dòng)的、異步的API。
把官網(wǎng)下下來的mina框架導(dǎo)入到idea里面,并創(chuàng)建一個(gè)Main類來啟動(dòng)mina!
<pre>
public class Main {
public static void main(String args[]) throws IOException {
NioSocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.setHandler(new SocketHandler());
acceptor.getFilterChain().addLast("TextLineCodec",new ProtocolCodecFilter(new TextLineCodecFactory()));
acceptor.bind(new InetSocketAddress(8000));//綁定本地端口
}
}
</pre>
NioSocketAcceptor.setHandler(IoHandler handler);給我們提供了監(jiān)聽Socket數(shù)據(jù)的類!我們需要重寫里面的監(jiān)聽方法,主要是重寫messageReceived方法!而每有一個(gè)Sesson加入,則mina會(huì)創(chuàng)建一個(gè)IOsession對(duì)象,我們需要將其保存起來,然后將session的數(shù)據(jù),傳送給其它Session。而數(shù)據(jù)對(duì)象,則是客戶端中需要的數(shù)據(jù),即是,UserLocation類,而,我們需要重寫SessionId數(shù)據(jù),返回給客戶端說,這個(gè)是哪個(gè)客戶端發(fā)送出來的
<pre>
public String reformatData(String data, int sessionId) {
String marker = "@location";
if (data.startsWith(marker)){
UserLocation userLocation = gson.fromJson(data.replace(marker, ""), UserLocation.class);
userLocation.setSessionId(sessionId);
System.out.println(marker + gson.toJson(userLocation));
return marker + gson.toJson(userLocation);
}
return data;
}
</pre>
當(dāng)服務(wù)器在接收到新Session加入的時(shí)候,需要將Session加入服務(wù)器數(shù)組里面,同樣退出的時(shí)候需要將session從數(shù)組里面remove出去。
<pre>
public void sessionCreated(IoSession session) throws Exception {
System.out.println("System create");
sessions.add(session);
for (IoSession ioSession : sessions) {
if (ioSession != session) {
ioSession.write("@create session");
}
}
}
public void sessionClosed(IoSession session) throws Exception {
System.out.println("session closed");
if (sessions.contains(session)) {
sessions.remove(session);
}
}
</pre>
當(dāng)服務(wù)器接受到客戶端傳來的消息,需要將數(shù)據(jù)分發(fā)到其它客戶端去!
<pre>
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
String str = (String) message;
if (str.equals("@quit")) {
sessions.remove(session);
return;
}
for (IoSession ioSession : sessions) {
if (ioSession != session) {
str = reformatData(str, sessions.indexOf(session));
ioSession.write(str);
}
}
}
</pre>
其實(shí)相對(duì)于客戶端,服務(wù)端的代碼相對(duì)簡單,因?yàn)榛赼pache mina,異步Socket處理代碼都已經(jīng)封裝好,只需要將獲取到的數(shù)據(jù)格式化后分發(fā)給其它客戶端就可以了!