以前开发,很少用的设计模式,即使是最简单的单例模式。
公司有一个项目要求实现socket客户端长连接,并实现自动重连。心想,如果是长连接的话,那么肯定你的客户端端口不能变。需要绑定端口。同时要没5秒发一次心跳。因为对象绑定,所以不能重新new一个channel。当时第一反应就是单例。可能会有别的更好的方法。可以限于技术有限。不说那么多,上关键代码。不好的地方请指点,往大家勿喷!
private static MySocketClient mySocketClient; private Selector selector; private SocketChannel sc ; private MySocketClient(String ip,int port){ try { this.init(ip, port); } catch (Exception e) { e.printStackTrace(); } } public static MySocketClient getInstance(String ip,int port){ if(mySocketClient == null){ mySocketClient = new MySocketClient(ip,port); } return mySocketClient; } public void init(String ip,int port) throws Exception{ try { selector = Selector.open(); sc = SocketChannel.open(); sc.socket().bind(new InetSocketAddress(Config.getLocalhostPort())); boolean b = sc.connect(new InetSocketAddress(InetAddress.getByName(ip), port)); System.out.println("是否连接: "+b); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); new Thread(new Listener(selector)).start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void sendMessage(String msg){ try { sc.write(ByteBuffer.wrap(msg.getBytes("gbk"))); } catch (IOException e) { try { sc.close(); mySocketClient = null; } catch (IOException e1) { e1.printStackTrace(); } e.printStackTrace(); } }
Timer timer = new Timer(); timer.schedule(new MyTask(), 1000*2, 1000*20);
public class MyTask extends TimerTask { @Override public void run() { MySocketClient myc = MySocketClient.getInstance(Config.getHostIp(), Config.getHostPort()); myc.sendMessage("$PX\r\n"); } }