mina传输实现数据推送
来源:互联网 发布:低头族事故案数据调查 编辑:程序博客网 时间:2024/06/08 05:32
网上找的一些资料,整理一下
加上自己的理解写的一个Demo
注意:需要的包有这些:
<!-- mina -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-integration-beans</artifactId>
<version>2.0.13</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.13</version>
<type>bundle</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-integration-spring</artifactId>
<version>1.1.7</version>
</dependency>
1.客户端
package com.single.mina.Demo;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import com.single.mina.Demo.Util.ClientConstantUtil;
public class MinaScoketClient{
private ClientConstantUtil constan;
public void StateCount(){
//建立对象传输工厂》可以传大数据量
ObjectSerializationCodecFactory factory = new ObjectSerializationCodecFactory();
factory.setDecoderMaxObjectSize(Integer.MAX_VALUE);
factory.setEncoderMaxObjectSize(Integer.MAX_VALUE);
//创建一个套接字连接诶
IoConnector connector = new NioSocketConnector();
//设置超时时间
connector.setConnectTimeoutMillis(ClientConstantUtil.getTime());
//设置读缓冲,传输的内容必须小于此缓冲
//connector.getSessionConfig().setReadBufferSize(2048*2048);
//添加内置日志
connector.getFilterChain().addLast("log", new LoggingFilter());
//设置编码过滤器
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.forName("utf-8"))));
/* connector.getFilterChain().addLast("volume",new ProtocolCodecFilter(factory));*/
//设置适配器(监听)
connector.setHandler(new ClientHandle(){
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionClosed(org.apache.mina.core.session.IoSession)
* 连接关闭时调用
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("连接关闭时调用");
for(;;){
try {
Thread.sleep(10000);
System.out.println("重连测试");
ConnectFuture future = connector.connect(new InetSocketAddress(ClientConstantUtil.getHost(),ClientConstantUtil.getProt()));
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
if(session.isConnected()){
System.out.println("断线重连成功");
break;
}
} catch (Exception e){
System.out.println("重连失败,10秒后重连");
}
}
//super.sessionClosed(session);
}
});
IoSession session;
boolean bool = true;
for(;;){
try {
if(bool==false){
Thread.sleep(10000);
}
System.out.println("建立连接测试");
ConnectFuture future = connector.connect(new InetSocketAddress(ClientConstantUtil.getHost(),ClientConstantUtil.getProt()));
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
//判断是否连上
if(session.isConnected()){
constan =ClientConstantUtil.getLoadBalancer();
constan.setSession(session);
break;
}
} catch (Exception e) {
bool = false;
System.out.println("连接失败,10秒后重连");
}
}
//等待session关闭
/* session.getCloseFuture().awaitUninterruptibly();*/
//释放connector
/* connector.dispose();*/
}
}
2.客户端监听
package com.single.mina.Demo;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
public class ClientHandle extends IoHandlerAdapter{
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache.mina.core.session.IoSession)
* 创建连接时调用
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("创建连接时调用");
super.sessionCreated(session);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache.mina.core.session.IoSession)
* 连接打开时调用
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("连接打开时调用");
super.sessionOpened(session);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionIdle(org.apache.mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
* 连接等待时调用
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
// TODO Auto-generated method stub
System.out.println("连接等待时调用");
super.sessionIdle(session, status);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache.mina.core.session.IoSession, java.lang.Throwable)
* 连接报错时调用
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
System.out.println("连接报错时调用");
super.exceptionCaught(session, cause);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object)
* 接收数据时调用
*/
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
// TODO Auto-generated method stub
System.out.println("接收数据时调用");
System.out.println("客户端接收到的消息是"+message.toString());
Thread.sleep(2000);
//接收心跳信息
if(message.toString().equals("1X11")){
session.write("1X12");
}
super.messageReceived(session, message);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#messageSent(org.apache.mina.core.session.IoSession, java.lang.Object)
* //当消息调用IoSession.write,返回消息
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
System.out.println("发送数据时调用");
super.messageSent(session, message);
}
}
3.服务端
package com.single.mina.Demo;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import javaxintioa.KeepAlive;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
//不用xml配置文件时可以这样写
public class MinaScoketServer{
public void StarServer(){
//创建一个非阻塞通道
IoAcceptor acceptor=new NioSocketAcceptor();
//设置读缓冲
acceptor.getSessionConfig().setReadBufferSize(2048);
//读写通道在5秒内无任何操作进入空闲状态--因为心跳包中加了空闲,该段代码可能失效
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,5);
//绑定监听
acceptor.setHandler(new ServerHandle());
//心跳包设置
KeepAliveMessageFactory keep = new MyKeepAliveMessageFactory();
//心跳包超时断开连接
MyKeepAliveRequestTimeoutHandlerImpl heartbeatImpt = new MyKeepAliveRequestTimeoutHandlerImpl();
//空闲执行心跳
KeepAliveFilter heartBeat = new KeepAliveFilter(keep,IdleStatus.BOTH_IDLE,heartbeatImpt);
// 是否回发
//heartBeat.setForwardEvent(false);
// 发送频率
heartBeat.setRequestInterval(15);
//设置编码Filter拦截器,读取
/*acceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(
Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter. WINDOWS.getValue())
)
);*/
//设置自定义的Filter拦截器,读取
acceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.forName("utf-8"))));
//绑定
acceptor.getFilterChain().addLast("heartBeat", heartBeat);
try {
//绑定套接字,绑定端口
acceptor.bind(new InetSocketAddress(81));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("服务端以启动");
/*new Thread(){
public void run(){
int i =0;
while(true){
System.out.println(i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();*/
}
}
4.服务端监听
package com.single.mina.Demo;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import net.sf.json.JSONObject;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.dom4j.Entity;
import com.single.mina.Demo.Util.ClientPacketMina;
import com.single.mina.Demo.Util.QueueUtil;
import com.single.mina.Demo.Util.QueuelistUtil;
public class ServerHandle extends IoHandlerAdapter {
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache.mina.core.session.IoSession)
* 创建连接时调用
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("服务端创建连接时调用");
super.sessionCreated(session);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache.mina.core.session.IoSession)
* 连接打开时调用
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("服务端连接打开时调用");
super.sessionOpened(session);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#sessionIdle(org.apache.mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
* 连接等待时调用
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
// TODO Auto-generated method stub
System.out.println("服务端连接等待时调用");
super.sessionIdle(session, status);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache.mina.core.session.IoSession, java.lang.Throwable)
* 连接报错时调用
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
System.out.println("服务端连接报错时调用+Session:"+session+"错误"+cause);
session.closeOnFlush();
super.exceptionCaught(session, cause);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object)
* 接收数据时调用
*/
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println("接收数据时调用");
InetAddress IP = ((InetSocketAddress)session.getRemoteAddress()).getAddress();
System.out.println(IP);
if(message!=null&&session!=null){
JSONObject json = JSONObject.fromObject(message.toString());
ClientPacketMina jsondate = (ClientPacketMina)JSONObject.toBean(json,ClientPacketMina.class);
System.out.println(jsondate.getDateJson());
QueueUtil queue = new QueueUtil();
//保存所有Session
Hashtable<String,QueueUtil> quelist = QueuelistUtil.getqueue().getList();
boolean bool = true;
//迭代判断该Session是否保存。
Iterator<String> itr = quelist.keySet().iterator();
while (itr.hasNext()){
String str = (String)itr.next();
if(jsondate.getClientId().equals(str)){
bool =false;
break;
}
System.err.println(str+" (while) "+quelist.get(str));
}
//在队列中不存在,保存到队列中
if(bool){
queue.setClientId(jsondate.getClientId());
queue.setIP(jsondate.getDateJson());
//获取单例队列
QueuelistUtil.getqueue().getList().put(queue.getClientId(),queue);
}
}
//session.write("2222222");
super.messageReceived(session, message);
}
/*
* (non-Javadoc)
* @see org.apache.mina.core.service.IoHandlerAdapter#messageSent(org.apache.mina.core.session.IoSession, java.lang.Object)
* 发送数据时调用
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
}
}
5.自己定义编码,当然也可以用mina自带的
package com.single.mina.Demo;
import java.nio.charset.Charset;
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;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineDecoder;
import org.apache.mina.filter.codec.textline.TextLineEncoder;
/*
* 可以自己写编码
*/
public class MyCodeFactory implements ProtocolCodecFactory{
private final TextLineEncoder encoder;
private final TextLineDecoder decoder;
public MyCodeFactory() {
this(Charset.forName("UTF-8"));
}
public MyCodeFactory(Charset charset) {
encoder = new TextLineEncoder(charset, LineDelimiter.UNIX);
decoder = new TextLineDecoder(charset, LineDelimiter.AUTO);
}
public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
return decoder;
}
public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
return encoder;
}
public int getEncoderMaxLineLength() {
return encoder.getMaxLineLength();
}
public void setEncoderMaxLineLength(int maxLineLength) {
encoder.setMaxLineLength(maxLineLength);
}
public int getDecoderMaxLineLength() {
return decoder.getMaxLineLength();
}
public void setDecoderMaxLineLength(int maxLineLength) {
decoder.setMaxLineLength(maxLineLength);
}
}
6.mina自带的心跳包
package com.single.mina.Demo;
import java.net.InetSocketAddress;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
public class MyKeepAliveMessageFactory implements KeepAliveMessageFactory{
/** 心跳包内容 */
private static final String HEARTBEATREQUEST = "1X11";
private static final String HEARTBEATRESPONSE = "1X12";
//这个接口是用来获取一个心跳请求包。
public Object getRequest(IoSession session) {
System.out.println("请求预设信息心跳请求: " + HEARTBEATREQUEST);
return HEARTBEATREQUEST;
}
//这个接口是用来获取一个心跳回复包。
public Object getResponse(IoSession session, Object request) {
System.out.println("响应预设信息心跳回复: " + HEARTBEATRESPONSE);
/** 返回预设语句 */
return HEARTBEATRESPONSE;
}
//这个接口就是用来判断接收到的消息是不是一个心跳请求包。
public boolean isRequest(IoSession session, Object message) {
/*System.out.println("请求心跳包信息: " + message);*/
System.out.println("请求心跳包地址心跳请求:"+((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress());
if(message.equals(HEARTBEATREQUEST))
return true;
return false;
}
//这个接口就是用来判断接收到的消息是不是一个心跳回复包。
public boolean isResponse(IoSession session, Object message) {
/*System.out.println("响应心跳包信息: " + message);*/
System.out.println("请求心跳包地址回复:"+((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress());
if(message.equals(HEARTBEATRESPONSE))
return true;
return false;
}
}
7.心跳超时
package com.single.mina.Demo;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
public class MyKeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler {
@Override
public void keepAliveRequestTimedOut(KeepAliveFilter filter,
IoSession session) throws Exception {
System.out.println("服务器端心跳包发送超时处理(即长时间没有发送(接受)心跳包)---关闭当前长连接");
CloseFuture closeFuture = session.close(true);
closeFuture.addListener(new IoFutureListener<IoFuture>() {
public void operationComplete(IoFuture future) {
if (future instanceof CloseFuture) {
((CloseFuture) future).setClosed();
System.out.println("sessionClosed 关闭,连接断开-->"+ future.getSession().getId());
}
}
});
}
}
8.启动服务端
package com.single.mina.Demo;
public class StarServer {
public static void main(String arg[]){
MinaScoketServer scoket = new MinaScoketServer();
scoket.StarServer();
}
}
9.启动客户端
package com.single.mina.Demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import net.sf.json.JSONObject;
import org.apache.mina.core.session.IoSession;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.single.mina.Demo.Util.ClientConstantUtil;
import com.single.mina.Demo.Util.ClientPacketMina;
public class StarMina{
/* public StarMina(){
new Thread(){
public void run(){
MinaScoketClient client = new MinaScoketClient();
client.StateCount();
}
}.start();
}*/
private static String msg = null;
public static void main(String atg[]){
createConnection();
}
//创建连接
public static void createConnection(){
new Thread(){
@Override
public void run() {
MinaScoketClient client = new MinaScoketClient();
client.StateCount();
try {
//3秒后传值》数据传输
Thread.sleep(3000);
dongtai();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
//数据传输
public static void transmitData(String datejson){
//对传输的数据封包
ClientPacketMina packet = new ClientPacketMina();
packet.setClientId("1");
packet.setDateJson(datejson);
packet.setIP("3");
//业务标识
packet.setBusinesslogo("");
//命令字
packet.setCommandword("");
//客户端得到唯一IOSession保存
IoSession session = ClientConstantUtil.getLoadBalancer().getSession();
//《!--实体转成json--》
ObjectMapper mapper = new ObjectMapper();
String aa ="";
try {
aa = mapper.writeValueAsString(packet);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
JSONObject json = JSONObject.fromObject(aa);
//《!--实体转成json--》
session.write(json);
}
//动态传输
public static void dongtai(){
while(true){
Scanner scann = new Scanner(System.in);
System.out.println("输入传的数据");
String a = scann.next();
transmitData(a);
}
}
//得到某个文本里的东西
/*public static String Fileout(){
File fiel = new File("D:/hello/hello.txt");
String ab ="";
try {
FileOutputStream out = new FileOutputStream(fiel);
for(int i = 0;i<100000;i++){
try {
out.write("你好".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
FileInputStream input = new FileInputStream(fiel);
byte[] b = new byte[(int) fiel.length()];
int count =0;
int temp = 0;
while((temp=input.read())!=-1){
b[count++]=(byte)temp;
}
input.close();
ab = new String(b);
} catch (IOException e) {
e.printStackTrace();
}
return ab;
}*/
}
11.下面是实体工具包
11.1
package com.single.mina.Demo.Util;
import org.apache.mina.core.session.IoSession;
public class ClientConstantUtil {
private static ClientConstantUtil instance;
//服务端IP
private final static String host = "127.0.0.1";
//端口
private final static Integer prot = 81;
//超时时间》》按毫秒计算
private final static Integer time = 20000;
//保存ioSession
private IoSession session;
//公有静态成员方法,返回唯一实例 (单例)
public static ClientConstantUtil getLoadBalancer() {
if (instance == null) {
instance = new ClientConstantUtil();
}
return instance;
}
public static Integer getTime() {
return time;
}
public static String getHost() {
return host;
}
public static Integer getProt() {
return prot;
}
public IoSession getSession() {
return session;
}
public void setSession(IoSession session) {
this.session = session;
}
}
11.2
package com.single.mina.Demo.Util;
import java.util.Map;
import org.apache.commons.collections.map.HashedMap;
public class ClientPacketMina{
//客户端标识
private String clientId;
//传数据
private String dateJson;
//ip地址
private String IP;
//命令字
private String Commandword;
//业务标识
private String Businesslogo;
public String getCommandword() {
return Commandword;
}
public void setCommandword(String commandword) {
Commandword = commandword;
}
public String getBusinesslogo() {
return Businesslogo;
}
public void setBusinesslogo(String businesslogo) {
Businesslogo = businesslogo;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getDateJson() {
return dateJson;
}
public void setDateJson(String dateJson) {
this.dateJson = dateJson;
}
public String getIP() {
return IP;
}
public void setIP(String iP) {
IP = iP;
}
}
11.3
package com.single.mina.Demo.Util;
import java.util.Hashtable;
public class QueuelistUtil {
//队列保存在Hashable,线程安全
private static Hashtable<String,QueueUtil> list = new Hashtable<String, QueueUtil>();
//单例创建
private static QueuelistUtil queue = null;
public static Hashtable<String, QueueUtil> getList() {
return list;
}
public static void setList(Hashtable<String, QueueUtil> list) {
QueuelistUtil.list = list;
}
public static QueuelistUtil getqueue(){
if(queue==null){
queue = new QueuelistUtil();
}
return queue;
}
}
11.4
package com.single.mina.Demo.Util;
import org.apache.mina.core.session.IoSession;
public class QueueUtil {
public QueueUtil(){
}
//设置公共的session类
private IoSession session;
private String clientId;
private String IP;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getIP() {
return IP;
}
public void setIP(String iP) {
IP = iP;
}
}
- mina传输实现数据推送
- mina实现长连接 推送
- MINA数据同步实现
- Mina实现传输对象的编解码
- 【mina】mina传输对象
- spring集成mina,包含心跳检测,实现服务端主动推送
- spring集成mina 实现消息推送以及转发
- 用mina传输文件
- mina传输文件
- mina 传输图片
- Mina自定义协议-实现数据交互
- 服务器数据推送功能实现
- 实现WCF传输大数据
- Mina APR传输与串口传输讲解
- 使用Mina传输Java对象
- mina对象压缩后传输
- 基于Mina实现的一个简单数据采集中间件
- ZK Server Push实现数据主动推送
- 淘汰赛后续
- 模板方法模式(组件协作)
- 剑指offer: 二叉树的下一个结点
- python basic configuration in linux
- python selenium常见问题之一
- mina传输实现数据推送
- 安卓四大组件之一-----活动
- matlab实现PS算法之自动色阶
- Spring--装配普通属性
- linux高端内存
- OpenCV:OpenCV目标检测Adaboost+haar源代码分析
- mysql大数据分库和分表 php解决方案
- 桥梁模式(单一职责)
- Linux最常用的命令总结