Mina长连接的使用

APP里面一直使用的是极光推送,推送时间有时候好,有时候差,所以一直想自己做APP长连接,自己做推送服务。网上找了 这个视频学习,https://www.imooc.com/learn/223,觉得还是讲的蛮好的,使用的MINA框架实现的。
讲的样例是实现消息推送的机制,我自己实现的样例是实现2个客户端实现消息互发。

消息推送这种一般要实现XMPP协议,我这里的样例为了简单起见,我就用户JSON传输数据。
话不多说,直接上代码吧。

服务端

需要引用的JAR包

        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.0.16</version>
        </dependency> 

默认开启服务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="   
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd   
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd   
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd   
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd   
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd  "
    default-lazy-init="false">


    <bean id="socketAddress" class="com.cat.mina.MinaServer" >
    </bean>

</beans>
package com.cat.mina;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public final class MinaServer{

   private final  NioSocketAcceptor acceptor = new NioSocketAcceptor();

   public MinaServer(){
      try{
         acceptor.setHandler(new MinaServerHandler());
         acceptor.getFilterChain().addLast("codecc", new ProtocolCodecFilter(new MinaTextFactory()));
         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5);
         acceptor.bind(new InetSocketAddress(5222));
      }catch(IOException e){
         e.printStackTrace();
      }
   }

}
package com.cat.mina;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;


public class MinaTextFactory implements ProtocolCodecFactory{

   private MinaTextEncode encode;

   private MinaTextDecode decode;

   public MinaTextFactory(){
      encode = new MinaTextEncode();
      decode = new MinaTextDecode();
   }

   @Override
   public ProtocolDecoder getDecoder(IoSession arg0)
         throws Exception{
      // TODO Auto-generated method stub
      return decode;
   }

   @Override
   public ProtocolEncoder getEncoder(IoSession arg0)
         throws Exception{
      // TODO Auto-generated method stub
      return encode;
   }

}
package com.cat.mina;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;


public class MinaTextDecode implements ProtocolDecoder{

   @Override
   public void decode(IoSession session,
                      IoBuffer in,
                      ProtocolDecoderOutput out)
         throws Exception{
      int start = in.position();
      while(in.hasRemaining()){
         byte b = in.get();
         if(b == '\n'){
            //遇到換行之后就是一行
            int current = in.position();
            int limit = in.limit();
            in.position(start);
            in.limit(current);
            IoBuffer buf = in.slice();
            byte[] dest = new byte[buf.limit()];
            buf.get(dest);
            String str = new String(dest);
            out.write(str);
            in.position(current);
            in.limit(limit);
         }
      }
   }

   @Override
   public void dispose(IoSession arg0)
         throws Exception{
      // TODO Auto-generated method stub

   }

   @Override
   public void finishDecode(IoSession arg0,
                            ProtocolDecoderOutput arg1)
         throws Exception{
      // TODO Auto-generated method stub

   }

}
package com.cat.mina;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;


public class MinaTextEncode implements ProtocolEncoder{

   @Override
   public void dispose(IoSession arg0)
         throws Exception{
      // TODO Auto-generated method stub

   }

   @Override
   public void encode(IoSession session,
                      Object arg1,
                      ProtocolEncoderOutput out)
         throws Exception{
      String s= null;
      if(arg1 instanceof String){
         s = (String) arg1;
      }
      if(s != null){
         CharsetEncoder charsetEncoder = (CharsetEncoder)session.getAttribute("encoder");
         if(null == charsetEncoder){
            charsetEncoder = Charset.defaultCharset().newEncoder();
            session.setAttribute("encoder",charsetEncoder);
         }
         IoBuffer ioBuffer = IoBuffer.allocate(s.length());
         ioBuffer.setAutoExpand(true);
         ioBuffer.putString(s, charsetEncoder);
         ioBuffer.flip();
         out.write(ioBuffer);
      }
   }

}

最重要的是 HANDER类

package com.cat.mina;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import com.cat.common.json.RJson;
import com.cat.common.lang.RString;


public class MinaServerHandler implements IoHandler{

   private static final Logger log = Logger.getLogger(MinaServerHandler.class);

   public static Map<String, IoSession> map = new HashMap<String, IoSession>();

   public static String User_Name = "userName";

   @Override
   public void exceptionCaught(IoSession arg0,
                               Throwable arg1)
         throws Exception{
      System.out.println("exceptionCaught");
      // TODO Auto-generated method stub
   }

   @Override
   public void inputClosed(IoSession arg0)
         throws Exception{
      System.out.println("inputClosed");
      // TODO Auto-generated method stub

   }

   @Override
   public void messageReceived(IoSession session,
                               Object arg1)
         throws Exception{
      String d = (String)arg1;
      System.out.println("messageReceived:"+d);
      Map<String, Object> m = null;
      try{
         m =  RJson.parseJson2Map(d);
      }catch(Exception e){
         e.printStackTrace();
      }
      if(null != m){
         String type = RString.toString(m.get("type"));
         if("register".equalsIgnoreCase(type)){
            //注册
            String userName = RString.toString(m.get("userName"));
            if(RString.isBlank(userName)){

               sendMsgToClient(session, "register need userName,but is null");
               return;
            }
            session.setAttribute(User_Name, userName);
            map.put(userName, session);
            sendMsgToClient(session, "register success");
            return;
         }else if("sendMsg".equalsIgnoreCase(type)){
            String msg = RString.toString(m.get("msg"));
            String to = RString.toString(m.get("to"));
            sendMsgToOtherClient(session, to, msg);
         }

      }

   }

   public static void sendMsgToOtherClient(IoSession session,String to,
                                      String msg){
      IoSession toSession  = map.get(to);
      if(null == toSession){
         sendMsgToClient(session,"is not online");
         return;
      }
      sendMsgToClient(toSession,msg);
      sendMsgToClient(session,"msg send Ok");
   }

   public static void sendMsgToClient(IoSession session,
                                      String msg){
      session.write(msg+"\n");
   }


   @Override
   public void messageSent(IoSession arg0,
                           Object arg1)
         throws Exception{
      System.out.println("messageSent");
   }

   @Override
   public void sessionClosed(IoSession arg0)
         throws Exception{
      System.out.println("sessionClosed");
   }

   @Override
   public void sessionCreated(IoSession session)
         throws Exception{
      log.info("IoSession created  address="+session.getRemoteAddress());
      System.out.println("sessionCreated");
   }

   @Override
   public void sessionIdle(IoSession arg0,
                           IdleStatus arg1)
         throws Exception{
      System.out.println("sessionIdle");
   }

   @Override
   public void sessionOpened(IoSession arg0)
         throws Exception{
      System.out.println("sessionOpened");
   }

}

客户端

package com.luoy;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;


public class SocketClient{

   public static void main(String[] args){
      SocketClient cliCllient = new SocketClient();
      cliCllient.start();
   }


   public void start(){
      BufferedReader inputReader = null;
      BufferedReader socketReder = null;
      BufferedWriter write = null;
      Socket socket = null;
      try{
         socket = new Socket("192.168.2.77", 5222);
         write = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
         socketReder = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         inputReader = new BufferedReader(new InputStreamReader(System.in));
         startServerRead(socketReder);
         String str;
         while(!(str = inputReader.readLine()).equalsIgnoreCase("bye")){
            write.write(str+"\n");
            write.flush();
         }
         System.out.println("end");
      }catch(IOException e){
         // TODO Auto-generated catch block
         e.printStackTrace();
      }finally{
          try {
            socket.close();
              write.close();
              inputReader.close();
              socketReder.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      }
   }


   public void startServerRead(final BufferedReader read){
       new Thread(new Runnable() {

        @Override
        public void run() {
            String response = null;
            try {
                while((response = read.readLine()) != null){
                    System.out.println("client get msg:"+response);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
   }
}

开启2个客户端之后,就能实现对话了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值