zoukankan      html  css  js  c++  java
  • JAVA长连接demo

    http://blog.csdn.net/caomiao2006/article/details/38830475

     

    JAVA长连接demo

     分类:
     
    [java] view plain copy
     
    1. package houlei.csdn.keepalive;  
    2.   
    3. import java.io.Serializable;  
    4. import java.text.SimpleDateFormat;  
    5. import java.util.Date;  
    6.   
    7. /** 
    8.  * 维持连接的消息对象。 
    9.  * <p> 
    10.  * 创建时间:2010-7-18 上午12:22:09 
    11.  * @author HouLei 
    12.  * @since 1.0 
    13.  */  
    14. public class KeepAlive implements Serializable{  
    15.   
    16.     private static final long serialVersionUID = -2813120366138988480L;  
    17.   
    18.     /* 覆盖该方法,仅用于测试使用。 
    19.      * @see java.lang.Object#toString() 
    20.      */  
    21.     @Override  
    22.     public String toString() {  
    23.         return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+" 维持连接包";  
    24.     }  
    25.   
    26. }  

    [java] view plain copy
     
    1. package houlei.csdn.keepalive;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.InputStream;  
    5. import java.io.ObjectInputStream;  
    6. import java.io.ObjectOutputStream;  
    7. import java.net.Socket;  
    8. import java.net.UnknownHostException;  
    9. import java.util.concurrent.ConcurrentHashMap;  
    10.   
    11. /** 
    12.  *  C/S架构的客户端对象,持有该对象,可以随时向服务端发送消息。 
    13.  * <p> 
    14.  * 创建时间:2010-7-18 上午12:17:25 
    15.  * @author HouLei 
    16.  * @since 1.0 
    17.  */  
    18. public class Client {  
    19.   
    20.     /** 
    21.      * 处理服务端发回的对象,可实现该接口。 
    22.      */  
    23.     public static interface ObjectAction{  
    24.         void doAction(Object obj,Client client);  
    25.     }  
    26.     public static final class DefaultObjectAction implements ObjectAction{  
    27.         public void doAction(Object obj,Client client) {  
    28.             System.out.println("处理: "+obj.toString());  
    29.         }  
    30.     }  
    31.     public static void main(String[] args) throws UnknownHostException, IOException {  
    32.         String serverIp = "127.0.0.1";  
    33.         int port = 65432;  
    34.         Client client = new Client(serverIp,port);  
    35.         client.start();  
    36.     }  
    37.       
    38.     private String serverIp;  
    39.     private int port;  
    40.     private Socket socket;  
    41.     private boolean running=false;  
    42.     private long lastSendTime;  
    43.     private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>();  
    44.       
    45.     public Client(String serverIp, int port) {  
    46.         this.serverIp=serverIp;this.port=port;  
    47.     }  
    48.       
    49.     public void start() throws UnknownHostException, IOException {  
    50.         if(running)return;  
    51.         socket = new Socket(serverIp,port);  
    52.         System.out.println("本地端口:"+socket.getLocalPort());  
    53.         lastSendTime=System.currentTimeMillis();  
    54.         running=true;  
    55.         new Thread(new KeepAliveWatchDog()).start();  
    56.         new Thread(new ReceiveWatchDog()).start();  
    57.     }  
    58.       
    59.     public void stop(){  
    60.         if(running)running=false;  
    61.     }  
    62.       
    63.     /** 
    64.      * 添加接收对象的处理对象。 
    65.      * @param cls 待处理的对象,其所属的类。 
    66.      * @param action 处理过程对象。 
    67.      */  
    68.     public void addActionMap(Class<Object> cls,ObjectAction action){  
    69.         actionMapping.put(cls, action);  
    70.     }  
    71.   
    72.     public void sendObject(Object obj) throws IOException {  
    73.         ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());  
    74.         oos.writeObject(obj);  
    75.         System.out.println("发送: "+obj);  
    76.         oos.flush();  
    77.     }  
    78.       
    79.     class KeepAliveWatchDog implements Runnable{  
    80.         long checkDelay = 10;  
    81.         long keepAliveDelay = 2000;  
    82.         public void run() {  
    83.             while(running){  
    84.                 if(System.currentTimeMillis()-lastSendTime>keepAliveDelay){  
    85.                     try {  
    86.                         Client.this.sendObject(new KeepAlive());  
    87.                     } catch (IOException e) {  
    88.                         e.printStackTrace();  
    89.                         Client.this.stop();  
    90.                     }  
    91.                     lastSendTime = System.currentTimeMillis();  
    92.                 }else{  
    93.                     try {  
    94.                         Thread.sleep(checkDelay);  
    95.                     } catch (InterruptedException e) {  
    96.                         e.printStackTrace();  
    97.                         Client.this.stop();  
    98.                     }  
    99.                 }  
    100.             }  
    101.         }  
    102.     }  
    103.       
    104.     class ReceiveWatchDog implements Runnable{  
    105.         public void run() {  
    106.             while(running){  
    107.                 try {  
    108.                     InputStream in = socket.getInputStream();  
    109.                     if(in.available()>0){  
    110.                         ObjectInputStream ois = new ObjectInputStream(in);  
    111.                         Object obj = ois.readObject();  
    112.                         System.out.println("接收: "+obj);  
    113.                         ObjectAction oa = actionMapping.get(obj.getClass());  
    114.                         oa = oa==null?new DefaultObjectAction():oa;  
    115.                         oa.doAction(obj, Client.this);  
    116.                     }else{  
    117.                         Thread.sleep(10);  
    118.                     }  
    119.                 } catch (Exception e) {  
    120.                     e.printStackTrace();  
    121.                     Client.this.stop();  
    122.                 }   
    123.             }  
    124.         }  
    125.     }  
    126.       
    127. }  

    [java] view plain copy
     
    1. package houlei.csdn.keepalive;  
    2.   
    3.   
    4. import java.io.IOException;  
    5. import java.io.InputStream;  
    6. import java.io.ObjectInputStream;  
    7. import java.io.ObjectOutputStream;  
    8. import java.net.ServerSocket;  
    9. import java.net.Socket;  
    10. import java.util.concurrent.ConcurrentHashMap;  
    11.   
    12. /** 
    13.  * C/S架构的服务端对象。 
    14.  * <p> 
    15.  * 创建时间:2010-7-18 上午12:17:37 
    16.  * @author HouLei 
    17.  * @since 1.0 
    18.  */  
    19. public class Server {  
    20.   
    21.     /** 
    22.      * 要处理客户端发来的对象,并返回一个对象,可实现该接口。 
    23.      */  
    24.     public interface ObjectAction{  
    25.         Object doAction(Object rev);  
    26.     }  
    27.       
    28.     public static final class DefaultObjectAction implements ObjectAction{  
    29.         public Object doAction(Object rev) {  
    30.             System.out.println("处理并返回:"+rev);  
    31.             return rev;  
    32.         }  
    33.     }  
    34.       
    35.     public static void main(String[] args) {  
    36.         int port = 65432;  
    37.         Server server = new Server(port);  
    38.         server.start();  
    39.     }  
    40.       
    41.     private int port;  
    42.     private volatile boolean running=false;  
    43.     private long receiveTimeDelay=3000;  
    44.     private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>();  
    45.     private Thread connWatchDog;  
    46.       
    47.     public Server(int port) {  
    48.         this.port = port;  
    49.     }  
    50.   
    51.     public void start(){  
    52.         if(running)return;  
    53.         running=true;  
    54.         connWatchDog = new Thread(new ConnWatchDog());  
    55.         connWatchDog.start();  
    56.     }  
    57.       
    58.     @SuppressWarnings("deprecation")  
    59.     public void stop(){  
    60.         if(running)running=false;  
    61.         if(connWatchDog!=null)connWatchDog.stop();  
    62.     }  
    63.       
    64.     public void addActionMap(Class<Object> cls,ObjectAction action){  
    65.         actionMapping.put(cls, action);  
    66.     }  
    67.       
    68.     class ConnWatchDog implements Runnable{  
    69.         public void run(){  
    70.             try {  
    71.                 ServerSocket ss = new ServerSocket(port,5);  
    72.                 while(running){  
    73.                     Socket s = ss.accept();  
    74.                     new Thread(new SocketAction(s)).start();  
    75.                 }  
    76.             } catch (IOException e) {  
    77.                 e.printStackTrace();  
    78.                 Server.this.stop();  
    79.             }  
    80.               
    81.         }  
    82.     }  
    83.       
    84.     class SocketAction implements Runnable{  
    85.         Socket s;  
    86.         boolean run=true;  
    87.         long lastReceiveTime = System.currentTimeMillis();  
    88.         public SocketAction(Socket s) {  
    89.             this.s = s;  
    90.         }  
    91.         public void run() {  
    92.             while(running && run){  
    93.                 if(System.currentTimeMillis()-lastReceiveTime>receiveTimeDelay){  
    94.                     overThis();  
    95.                 }else{  
    96.                     try {  
    97.                         InputStream in = s.getInputStream();  
    98.                         if(in.available()>0){  
    99.                             ObjectInputStream ois = new ObjectInputStream(in);  
    100.                             Object obj = ois.readObject();  
    101.                             lastReceiveTime = System.currentTimeMillis();  
    102.                             System.out.println("接收: "+obj);  
    103.                             ObjectAction oa = actionMapping.get(obj.getClass());  
    104.                             oa = oa==null?new DefaultObjectAction():oa;  
    105.                             Object out = oa.doAction(obj);  
    106.                             if(out!=null){  
    107.                                 ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());  
    108.                                 oos.writeObject(out);  
    109.                                 oos.flush();  
    110.                             }  
    111.                         }else{  
    112.                             Thread.sleep(10);  
    113.                         }  
    114.                     } catch (Exception e) {  
    115.                         e.printStackTrace();  
    116.                         overThis();  
    117.                     }   
    118.                 }  
    119.             }  
    120.         }  
    121.           
    122.         private void overThis() {  
    123.             if(run)run=false;  
    124.             if(s!=null){  
    125.                 try {  
    126.                     s.close();  
    127.                 } catch (IOException e) {  
    128.                     e.printStackTrace();  
    129.                 }  
    130.             }  
    131.             System.out.println("关闭:"+s.getRemoteSocketAddress());  
    132.         }  
    133.           
    134.     }  
    135.       
    136. }  

    大致解释一下什么意思:

    长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的。
    如果,长时间未发送维持连接包,服务端程序将断开连接。

    客户端:
    通过持有Client对象,可以随时(使用sendObject方法)发送Object给服务端。
    如果keepAliveDelay毫秒(程序中是2秒)内未发送任何数据,则,自动发送一个KeepAlive对象给服务端,
    用于维持连接。
    由于,我们向服务端,可以发送很多不同的对象,服务端也可以返回不同的对象。
    所以,对于返回对象的处理,要编写具体的ObjectAction实现类进行处理。
    通过Client.addActionMap方法进行添加。这样,程序会回调处理。

    服务端:
    由于客户端会定时(keepAliveDelay毫秒)发送维持连接的信息过来,所以,服务端要有一个检测机制。
    即当服务端receiveTimeDelay毫秒(程序中是3秒)内未接收任何数据,则,自动断开与客户端的连接。
    ActionMapping的原理与客户端相似(相同)。

    通过添加相应的ObjectAction实现类,可以实现不同对象的响应、应答过程。



    祝好运~~

  • 相关阅读:
    Mybatis 原始dao CRUD方法
    JQuery的焦点事件focus() 与按键事件keydown() 及js判断当前页面是否为顶级页面 子页面刷新将顶级页面刷新 window.top.location
    使用actionerror做失败登录验证
    Java项目中的下载 与 上传
    shiro框架 4种授权方式 说明
    javascript 中数组的创建 添加 与将数组转换成字符串 页面三种提交请求的方式
    序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询
    Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法
    orcal 数据库 maven架构 ssh框架 的全注解环境模版 maven中央仓库批量删除lastupdated文件后依然是lastupdated解决方法 mirror aliyun中央仓库
    EasyUI加zTree使用解析 easyui修改操作的表单回显方法 验证框提交表单前验证 datagrid的load方法
  • 原文地址:https://www.cnblogs.com/jukan/p/5272235.html
Copyright © 2011-2022 走看看