国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java如何實現長連接

Java如何實現長連接

2020-09-09 00:25崔笑顏 Java教程

這篇文章主要介紹了Java如何實現長連接,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下

實現原理:

長連接的維持,是要客戶端程序,定時向服務端程序,發送一個維持連接包的。
如果,長時間未發送維持連接包,服務端程序將斷開連接。

客戶端:

Client通過持有Socket的對象,可以隨時(使用sendObject方法)發送Massage Object(消息)給服務端。
如果keepAliveDelay毫秒(程序中是2秒)內未發送任何數據,則自動發送一個KeepAlive Object(心跳)給服務端,用于維持連接。
由于,我們向服務端,可以發送很多不同的消息對象,服務端也可以返回不同的對象。所以,對于返回對象的處理,要編寫具體的ObjectAction實現類進行處理。通過Client.addActionMap方法進行添加。這樣,程序會回調處理。

服務端:

由于客戶端會定時(keepAliveDelay毫秒)發送維持連接的信息過來,所以,服務端要有一個檢測機制。
即當服務端receiveTimeDelay毫秒(程序中是3秒)內未接收任何數據,則自動斷開與客戶端的連接。
ActionMapping的原理與客戶端相似(相同)。
通過添加相應的ObjectAction實現類,可以實現不同對象的響應、應答過程。

心跳反映的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.excel.keepalive;
 
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
    *
    * 維持連接的消息對象(心跳對象)
    */
public class KeepAlive implements Serializable {
 
  private static final long serialVersionUID = -2813120366138988480L;
 
  /* 覆蓋該方法,僅用于測試使用。
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"\t維持連接包";
  }
 
}

服務端

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

客戶端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.java.excel.keepalive;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentHashMap;
 
public class Client {
 
  /**
   * 處理服務端發回的對象,可實現該接口。
   */
  public static interface ObjectAction{
    void doAction(Object obj,Client client);
  }
  
  public static final class DefaultObjectAction implements ObjectAction{
    public void doAction(Object obj,Client client) {
      System.out.println("處理:\t"+obj.toString());
    }
  }
  
  
  public static void main(String[] args) throws UnknownHostException, IOException {
    String serverIp = "127.0.0.1";
    int port = 65432;
    Client client = new Client(serverIp,port);
    client.start();
  }
  
  private String serverIp;
  private int port;
  private Socket socket;
  private boolean running=false; //連接狀態
  
  private long lastSendTime; //最后一次發送數據的時間
  
  //用于保存接收消息對象類型及該類型消息處理的對象
  private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>();
  
  public Client(String serverIp, int port) {
    this.serverIp=serverIp;
    this.port=port;
  }
  
  public void start() throws UnknownHostException, IOException {
    if(running)return;
    socket = new Socket(serverIp,port);
    System.out.println("本地端口:"+socket.getLocalPort());
    lastSendTime=System.currentTimeMillis();
    running=true;
    new Thread(new KeepAliveWatchDog()).start(); //保持長連接的線程,每隔2秒項服務器發一個一個保持連接的心跳消息
    new Thread(new ReceiveWatchDog()).start();  //接受消息的線程,處理消息
  }
  
  public void stop(){
    if(running)running=false;
  }
  
  /**
   * 添加接收對象的處理對象。
   * @param cls 待處理的對象,其所屬的類。
   * @param action 處理過程對象。
   */
  public void addActionMap(Class<Object> cls,ObjectAction action){
    actionMapping.put(cls, action);
  }
 
  public void sendObject(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
    oos.writeObject(obj);
    System.out.println("發送:\t"+obj);
    oos.flush();
  }
  
  class KeepAliveWatchDog implements Runnable{
    long checkDelay = 10;
    long keepAliveDelay = 1000;
    public void run() {
      while(running){
        if(System.currentTimeMillis()-lastSendTime>keepAliveDelay){
          try {
            Client.this.sendObject(new KeepAlive());
          } catch (IOException e) {
            e.printStackTrace();
            Client.this.stop();
          }
          lastSendTime = System.currentTimeMillis();
        }else{
          try {
            Thread.sleep(checkDelay);
          } catch (InterruptedException e) {
            e.printStackTrace();
            Client.this.stop();
          }
        }
      }
    }
  }
  
  class ReceiveWatchDog implements Runnable{
    public void run() {
      while(running){
        try {
          InputStream in = socket.getInputStream();
          if(in.available()>0){
            ObjectInputStream ois = new ObjectInputStream(in);
            Object obj = ois.readObject();
            System.out.println("接收:\t"+obj);
            ObjectAction oa = actionMapping.get(obj.getClass());
            oa = oa==null?new DefaultObjectAction():oa;
            oa.doAction(obj, Client.this);
          }else{
            Thread.sleep(10);
          }
        } catch (Exception e) {
          e.printStackTrace();
          Client.this.stop();
        }
      }
    }
  }
  
}

Java如何實現長連接

以上就是Java如何實現長連接的詳細內容,更多關于java實現長連接的資料請關注服務器之家其它相關文章!

原文鏈接:https://cloud.tencent.com/developer/article/1640058

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 山岸逢花在线观看 | 国产视频一区在线 | 午夜免费视频 | 成人av视屏| 欧美精品在线一区二区三区 | 欧美成人一区二区三区片免费 | 精品国产髙清在线看国产毛片 | 欧美麻豆 | 国产成人a亚洲精品 | 全部古装三级在线播放 | 国产精品一区久久久 | 91久久国产综合久久 | 亚洲黄色成人 | 成人精品在线视频 | 欧美精品亚洲 | 一区二区三区四区在线 | 黄色国产 | 91精品国产91久久久 | 99热国| 国产精品18久久久 | av日韩在线播放 | 中文字幕亚洲一区二区三区 | 黄色片免费| 激情五月婷婷基地 | 精品在线一区二区 | 日韩福利| 成人片免费视频 | 久久久久久久9 | 播放欧美一级片 | 91精品在线播放 | 在线观看av网站 | 欧美在线1 | 五月婷婷精品 | 免费精品| 羞羞视频免费网站 | 日日爽| 天天夜夜操 | 免费在线一区二区 | 免费的av网站 | 黄色网页在线 | 欧美不卡在线 |