1. Client
package com.msb.netty.testPageLongKeepAlive;
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();
new Thread(new ReceiveWatchDog()).start();
}
public void stop() {
if (running) running = false;
}
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();
}
}
}
}
}
2. Server
package com.msb.netty.testPageLongKeepAlive;
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());
}
}
}
3. Maintain the heartbeat of the message
package com.msb.netty.testPageLongKeepAlive;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
public class KeepAlive implements Serializable {
private static final long serialVersionUID = -2813120366138988480L;
@Override
public String toString() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\t维持连接包";
}
}