Yet another nio framework for java
項目名稱:Yanf4j(Yet another nio framework for java)項目地址:https://code.google.com/p/yanf4j/,當前版本0.30-beta1
協議:Apache License, Version 2.0
簡單描述:
有這麼多nio框架了,為什麼要another?重複造輪子也罷,這框架脫胎於一個服務器項目的網絡層代碼,期間參考了cindy、grizzly等nio框架的實現,加上自己的一些心得體會實現的。特點是簡單、小巧、超輕量級。項目沒有多大野心,目標是高效、簡單地實現非阻塞模式的Server(TCP、UDP)並且保證不錯的性能要求,不提供客戶端API 和阻塞模式。如果你的項目需要實現一個socket server並且不希望用太重量級的框架,yanf4j是個不錯的選擇。
例子,在source archive中帶有例子,這裏描述下tcp和udp的echo server的實現。
一、先看TCP的Echo Server
1、實現處理handler,繼承HandlerAdapter類,實現相應的回調方法,這與其他nio框架沒啥區別:
import com.google.code.yanf4j.nio.Dispatcher;
import com.google.code.yanf4j.nio.Session;
import com.google.code.yanf4j.nio.impl.HandlerAdapter;
import com.google.code.yanf4j.nio.util.DispatcherFactory;
public class EchoHandler extends HandlerAdapter<String> {
Dispatcher dispatcher = DispatcherFactory.newDispatcher(4);
@Override
public void onException(Session session, Throwable t) {
t.printStackTrace();
}
@Override
public void onMessageSent(Session session, String t) {
System.out.println("sent " + t + " to "
+ session.getRemoteSocketAddress());
}
@Override
public void onSessionStarted(Session session) {
System.out.println("session started");
session.setUseBlockingRead(true);
session.setUseBlockingWrite(false);
}
public void onSessionCreated(Session session) {
System.out.println(session.getRemoteSocketAddress().toString()
+ " connected");
}
public void onSessionClosed(Session session) {
System.out.println(session.getRemoteSocketAddress().toString()
+ " disconnected");
}
public void onReceive(final Session session, final String msg) {
System.out.println("recv:" + msg);
if (msg != null)
dispatcher.dispatch(new Runnable() {
public void run() {
if (msg.equals("q"))
session.close();
session.send(msg);
}
});
}
}
import com.google.code.yanf4j.nio.Session;
import com.google.code.yanf4j.nio.impl.HandlerAdapter;
import com.google.code.yanf4j.nio.util.DispatcherFactory;
public class EchoHandler extends HandlerAdapter<String> {
Dispatcher dispatcher = DispatcherFactory.newDispatcher(4);
@Override
public void onException(Session session, Throwable t) {
t.printStackTrace();
}
@Override
public void onMessageSent(Session session, String t) {
System.out.println("sent " + t + " to "
+ session.getRemoteSocketAddress());
}
@Override
public void onSessionStarted(Session session) {
System.out.println("session started");
session.setUseBlockingRead(true);
session.setUseBlockingWrite(false);
}
public void onSessionCreated(Session session) {
System.out.println(session.getRemoteSocketAddress().toString()
+ " connected");
}
public void onSessionClosed(Session session) {
System.out.println(session.getRemoteSocketAddress().toString()
+ " disconnected");
}
public void onReceive(final Session session, final String msg) {
System.out.println("recv:" + msg);
if (msg != null)
dispatcher.dispatch(new Runnable() {
public void run() {
if (msg.equals("q"))
session.close();
session.send(msg);
}
});
}
}
2、實現EchoServer,核心是TCPController類的使用:
Configuration configuration = new Configuration();
configuration.setStatisticsServer(true);
configuration.setTcpSessionReadBufferSize(256 * 1024); // 設置讀的緩衝區大小
AbstractController controller = new TCPController(configuration,
new StringCodecFactory());
controller.setPort(8080); // 設置端口
controller.setReadThreadCount(1); // 設置讀線程數,通常為1
controller.setReceiveBufferSize(16 * 1024); // 設置socket接收緩衝區大小
controller.setReuseAddress(false); // 設置是否重用端口
controller.setHandler(new EchoHandler()); // 設置handler
controller.setHandleReadWriteConcurrently(true); // 設置是否允許讀寫並發處理
controller.addStateListener(new ServerStateListener());
controller.start();
configuration.setStatisticsServer(true);
configuration.setTcpSessionReadBufferSize(256 * 1024); // 設置讀的緩衝區大小
AbstractController controller = new TCPController(configuration,
new StringCodecFactory());
controller.setPort(8080); // 設置端口
controller.setReadThreadCount(1); // 設置讀線程數,通常為1
controller.setReceiveBufferSize(16 * 1024); // 設置socket接收緩衝區大小
controller.setReuseAddress(false); // 設置是否重用端口
controller.setHandler(new EchoHandler()); // 設置handler
controller.setHandleReadWriteConcurrently(true); // 設置是否允許讀寫並發處理
controller.addStateListener(new ServerStateListener());
controller.start();
Configuration 默認會在classpath查找yanf4j.properties屬性文件,用於配置服務器屬性,然而,你也看到,可以編碼設置這些屬性,具體參考wiki。
3、然後?沒然後了,一個TCP的echo server已經搞定了,你可以telnet到8080端口試試了。
二、UDP的Echo server
1、handler,可以複用前麵的EchoHandler
2、UDP的核心類是UDPController:
Configuration configuration = new Configuration();
configuration.setTcpPort(8090);
configuration.setTcpReuseAddress(false);
configuration.setStatisticsServer(true);
configuration.setTcpNoDelay(true);
configuration.setTcpReadThreadCount(1);
configuration.setTcpRecvBufferSize(16 * 1024);
UDPController controller = new UDPController(configuration);
controller.setMaxDatagramPacketLength(1024);
controller.setHandler(new EchoHandler());
controller.start();
configuration.setTcpPort(8090);
configuration.setTcpReuseAddress(false);
configuration.setStatisticsServer(true);
configuration.setTcpNoDelay(true);
configuration.setTcpReadThreadCount(1);
configuration.setTcpRecvBufferSize(16 * 1024);
UDPController controller = new UDPController(configuration);
controller.setMaxDatagramPacketLength(1024);
controller.setHandler(new EchoHandler());
controller.start();
更多細節,請參考項目主頁上的wiki。
文章轉自莊周夢蝶 ,原文發布時間2008-10-11
最後更新:2017-05-18 11:01:58