通過mina框架來實現(xiàn)一個簡單的地圖實時位置共享,其實里面就相當(dāng)于做一個簡單的聊天室!客戶端A凌受,說我在這里,客戶端B說我在那里思杯,那么服務(wù)器就要存儲這兩個對象的會話胜蛉,而兩個對象,成為Session色乾!每一個客戶端添加進來誊册,則創(chuàng)建一個Session標(biāo)識,保持與服務(wù)器的長連接暖璧!
Apache Mina是一個能夠幫助用戶開發(fā)高性能和高伸縮性網(wǎng)絡(luò)應(yīng)用程序的框架案怯。它通過Java nio技術(shù)基于TCP/IP和UDP/IP協(xié)議提供了抽象的、事件驅(qū)動的澎办、異步的API殴泰。
把官網(wǎng)下下來的mina框架導(dǎo)入到idea里面于宙,并創(chuàng)建一個Main類來啟動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方法!而每有一個Sesson加入离咐,則mina會創(chuàng)建一個IOsession對象谱俭,我們需要將其保存起來,然后將session的數(shù)據(jù)宵蛀,傳送給其它Session昆著。而數(shù)據(jù)對象,則是客戶端中需要的數(shù)據(jù)术陶,即是凑懂,UserLocation類,而梧宫,我們需要重寫SessionId數(shù)據(jù)接谨,返回給客戶端說,這個是哪個客戶端發(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加入的時候塘匣,需要將Session加入服務(wù)器數(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>
其實相對于客戶端,服務(wù)端的代碼相對簡單驰徊,因為基于apache mina笤闯,異步Socket處理代碼都已經(jīng)封裝好,只需要將獲取到的數(shù)據(jù)格式化后分發(fā)給其它客戶端就可以了棍厂!