mina框架用来实现和服务端的推送功能。底层用了NioSocket,mina只是对NioSocket做了一层封装和优化。下面举个实现的栗子。 (依赖的jar包地址在文章末端)
服务端
public class MinaService {
private static final int PORT = 1144;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
BasicConfigurator.configure();
IoAcceptor ioAcceptor = new NioSocketAcceptor();
// 添加日志过滤器
ioAcceptor.getFilterChain().addLast("logger", new LoggingFilter());
ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));
ioAcceptor.setHandler(new AcceptHandle());
ioAcceptor.getSessionConfig().setReadBufferSize(2048);
ioAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); //Session的空闲时间 BOTH_IDLE读写都是一样的时间 单位:秒
ioAcceptor.bind(new InetSocketAddress(PORT));
System.out.println("服务器正在监听端口" + PORT + "...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static class AcceptHandle extends IoHandlerAdapter {
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionCreated(session);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionOpened(session);
}
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionClosed(session);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
super.messageSent(session, message);
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
super.messageReceived(session, message);
System.out.println("接收到:" + message.toString());
session.write("懵逼服务端发来贺电!");
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
// TODO Auto-generated method stub
super.exceptionCaught(session, cause);
System.out.println("服务器出现异常:" + cause);
}
}
}
客户端
1.MinaActivity:主Activity
2.MinaService:被Activity启动,主要功能为连接和关闭Mina连接。
import ConnectionManager,ConnectionConfig,SessionManager
3.ConnectionManager:管理Mina的开启、关闭,监听服务端的消息
4.SessionManager:管理和服务端连接的Session,这个Session用于发送消息给服务端
5.ConnectionConfig:利用构建者模式构建链接服务端的配置信息,如ip,port,bufferSize等
MinaActivity.java
public class MinaActivity extends AppCompatActivity {
private TextView mTv0;
private MessageBroadcastReceiver mReceiver;
private Intent mMinaServiceIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mina);
mTv0 = (TextView) findViewById(R.id.id_tv0);
initBroadcast();
startService();
}
private void initBroadcast() {
IntentFilter filter = new IntentFilter("com.test.mina");
mReceiver = new MessageBroadcastReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
}
private void unregistBroadcast() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
}
private void startService() {
mMinaServiceIntent = new Intent(this, MinaService.class);
startService(mMinaServiceIntent);
}
private void stopMinaService() {
stopService(mMinaServiceIntent);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregistBroadcast();
stopMinaService();
}
public void clickSend1(View view) {
try{
//这里前后加了123是为了让服务端能接收到,如果直接用中文接收不到,估计跟Filter有关,后续改进
String sendMsg = "123懵逼客户端001发来贺电!123";
mTv0.append("我\n" + sendMsg + "\n\n");
SessionManager.getInstance().writeToServer(sendMsg);
}catch ( Exception e){
e.printStackTrace();
}
}
private class MessageBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
mTv0.append("服务端\n" + intent.getStringExtra("DATA") + "\n\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
MinaService
public class MinaService extends Service {
private ConnectionThread mConnectionThread;
@Override
public void onCreate() {
super.onCreate();
mConnectionThread = new ConnectionThread("nima",getApplicationContext());
mConnectionThread.start();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
mConnectionThread.disConnection();
mConnectionThread = null;
}
private class ConnectionThread extends HandlerThread{
private Context mContext;
private ConnectionManager mManager;
private boolean mIsConnection;
public ConnectionThread(String name, Context context) {
super(name);
mContext = context;
ConnectionConfig config = new ConnectionConfig.Builder(mContext)
.setIp("192.168.250.126")
.setPort(1144)
.setReadBufferSize(10240)
.setConnectionTimeout(10000).builder();
mManager = new ConnectionManager(config);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
//不断连接,直到陈功为止
for(;;){
mIsConnection =mManager.connect();
if(mIsConnection){
break;
}
try{
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
}
System.out.println("已连接上服务端");
}
public void disConnection(){
mManager.disConnect();
}
}
}
ConnectionManager
public class ConnectionManager {
private final String Mina_Brocast_Action = "com.test.mina";
private ConnectionConfig mConfig;
private WeakReference<Context> mContext;
private NioSocketConnector mConnection;
private IoSession mSession;
private InetSocketAddress mAddreess;
public ConnectionManager(ConnectionConfig config) {
mConfig = config;
mContext = new WeakReference<Context>(mConfig.getContext());
init();
}
private void init(){
mAddreess = new InetSocketAddress(mConfig.getIp(),mConfig.getPort());
mConnection = new NioSocketConnector();
mConnection.setDefaultRemoteAddress(mAddreess);
mConnection.getSessionConfig().setReadBufferSize(mConfig.getReadBuffrerSize());
mConnection.getFilterChain().addLast("logger",new LoggingFilter());
mConnection.getFilterChain().addLast("codec",new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));
mConnection.setHandler(new AcceptHandle(mConfig.getContext()));
}
private class AcceptHandle extends IoHandlerAdapter {
private Context mContext;
public AcceptHandle(Context context){
mContext = context;
}
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionOpened(session);
//将Session保存到SessionManager中,用来后续发送消息用
SessionManager.getInstance().setSession(session);
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
super.messageReceived(session, message);
if(mContext != null){
Intent intent = new Intent(Mina_Brocast_Action);
intent.putExtra("DATA",message.toString());
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
}
}
}
public boolean connect(){
try{
ConnectFuture future = mConnection.connect();
future.awaitUninterruptibly();//一直等到连接位置
mSession = future.getSession();
return mSession != null;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
public void disConnect(){
mConnection.dispose();
mConnection = null;
mSession = null;
mAddreess = null;
mContext = null;
}
}
SessionManager
public class SessionManager {
private static SessionManager mManager;
private IoSession mSession;//最终和服务器通信的对象
public static SessionManager getInstance(){
if(mManager == null){
synchronized (SessionManager.class){
if(mManager == null){
mManager = new SessionManager();
}
}
}
return mManager;
}
public void setSession(IoSession session){
mSession = session;
}
public void writeToServer(Object msgObj){
if(null != mSession){
mSession.write(msgObj);
}
}
public void cloaseSection(){
if(null != mSession){
mSession.getCloseFuture().setClosed();
}
}
public void removeSession(){
mSession = null;
}
}
ConnectionConfig
public class ConnectionConfig {
private Context context;
private String ip;
private int port;
private int readBuffrerSize;
private long connectionTimeout;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getReadBuffrerSize() {
return readBuffrerSize;
}
public void setReadBuffrerSize(int readBuffrerSize) {
this.readBuffrerSize = readBuffrerSize;
}
public long getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(long connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public static class Builder{
private Context context;
private String ip = "192.168.136.2";
private int port = 1144;
private int readBuffrerSize = 10240;
private long connectionTimeout = 10000;
public Builder(Context context){
this.context = context;
}
public Builder setIp(String ip){
this.ip = ip;
return this;
}
public Builder setPort(int port){
this.port = port;
return this;
}
public Builder setReadBufferSize(int bufferSize){
this.readBuffrerSize = bufferSize;
return this;
}
public Builder setConnectionTimeout(long connectionTimeout){
this.connectionTimeout = connectionTimeout;
return this;
}
private void applyConfig(ConnectionConfig config){
config.context = this.context;
config.ip = this.ip;
config.port = this.port;
config.readBuffrerSize = this.readBuffrerSize;
config.connectionTimeout = this.connectionTimeout;
}
public ConnectionConfig builder(){
ConnectionConfig config = new ConnectionConfig();
applyConfig(config);
return config;
}
}
}