- 浏览: 523605 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (422)
- 重要 (12)
- BUG解决备忘录 (32)
- 环境搭建 (17)
- 开源组件 (4)
- 数据库 (16)
- 设计模式 (4)
- 测试 (3)
- javascript (5)
- Android (14)
- jdk相关 (9)
- struts2 (10)
- freemark (3)
- 自定义扩展及工具类 (5)
- jdk5新特性及java基础 (13)
- ssh及其他框架 (15)
- linux (32)
- tcp-ip http协议 (8)
- 服务器集群与负载均衡 (34)
- 项目管理相关 (11)
- 实用小技术 (10)
- 架构相关 (14)
- firefox组件 (11)
- spider (6)
- 产品设计 (11)
- PHP (1)
- ws (4)
- lucene (10)
- 其他 (2)
- BI (1)
- NoSQL (3)
- gzip (1)
- ext (4)
- db (6)
- socket (1)
- 源码阅读 (2)
- NIO (2)
- 图片处理 (1)
- java 环境 (2)
- 项目管理 (4)
- 从程序员到项目经理(一):没有捷径 (1)
- bug (1)
- JAVA BASE (8)
- 技术原理 (0)
- 新框架新技术 (1)
- 量化与python (1)
- 系统编程 (0)
- C语言 (0)
- 汇编 (0)
- 算法 (0)
最新评论
-
hyspace:
别逗了,最后一个算法根本不是最优的,sort(function ...
数组去重——一道前端校招试题 -
washingtin:
楼主能把策略和路由的类代码贴出来吗
Spring + iBatis 的多库横向切分简易解决思路 -
sdyjmc:
初略看了一下,没有闹明白啊,均衡负载使用Nginx,sessi ...
J2EE集群原理 I -
shandeai520:
谢谢大神!请教大神一个问题:假如我有三台服务器,连接池的上限是 ...
集群和数据库负载均衡的研究 -
hekuilove:
给lz推荐一下apache commonsStringUtil ...
request 获取 ip
最近在做一个项目,用到了远程调用方式,开始采用的是rmi,后来经过测试,rmi可能无法达到项目的一些性能上的要求,于是采用了基于tcp/udp的netty,但是直接用netty开发,有些麻烦了,我们想把服务抽取出来部署在远程服务器上,开发的兄弟们只是在自己的项目中负责调用一下,就跟rmi类似,非常方便。
但是又有一个问题,调用的兄弟需要在web中请求这种tcp服务,netty内部是异步处理机制,http是伪长连接,调用结束后,异步请求还没有返回,http连接就断开了,返回的是null。所以这个问题要解决一下。
下面说下封装的各个类的代码吧
首先当客户端对远程服务器发起tcp请求时,这时候请求一般会到达服务器端的handler里,我写的这个handler继承了netty的SimpleChannelUpstreamHandler,代码如下:
Java代码 收藏代码
public abstract class ChannelServerHandler extends SimpleChannelUpstreamHandler {
private final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelServerHandler.class);
protected final Map<String, InvokeHandler> handlers = new HashMap<String, InvokeHandler>();
protected final Map<String, Method> initMethods = new HashMap<String, Method>();
public ChannelServerHandler() {
WSCFInit.register(handlers, initMethods);
}
protected abstract void processor(Channel channel, Object message);
@Override
public final void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Transport t = (Transport) e.getMessage();
String className = t.getClazz();
String methodName = t.getMethod();
logger.info("Invoke Handler:" + className + ", Invoke Method:" + methodName);
processor(ctx.getChannel(), t);
}
里面有几个变量需要解释一下,handlers是开发tcp服务端的handler存放的map,initMethods是里面需要调用的方法,通过WSCFInit类来进行初始化工作。
它主要做了如下工作,在服务器端Server启动的时候,扫描固定包下的handler和他们的方法,然后以clazz+method的方式存放在handlers和initMthods这两个map中。
Java代码 收藏代码
Reflections reflections = new Reflections("packagename");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith((Class<? extends Annotation>) annClass);
Iterator<Class<?>> it = annotated.iterator();
while (it.hasNext()) {
Class<?> next = it.next();
if (next.isAnnotationPresent(Handler.class)) {
Annotation ann = (Annotation) next.getAnnotation((Class<? extends Annotation>) annClass);
handlers.put(((Handler) ann).name(), (InvokeHandler) next.newInstance());
Method[] methods = next.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Remote.class)) {
Remote path = method.getAnnotation(Remote.class);
initMethods.put(((Handler) ann).name() + path.url(), method);
}
}
}
}
protected abstract void processor(Channel channel, Object message);这个方法具体的逻辑是由它的子类来处理的。
再看一下ServerHandler类里面processor的代码,这个类继承了ChannelServerHandler
Java代码 收藏代码
@Override
protected void processor(Channel channel, Object message) {
Transport transport = (Transport) message;
InvokeHandler handler = handlers.get(transport.getClazz());
Object[] params = (Object[]) transport.getMessage();
Object ret = null;
try {
Method method = initMethods.get(transport.getClazz() + transport.getMethod());
if (method == null) {
} else {
ret = method.invoke(handler, params);
}
ServerSender sender = new ServerSender(channel, transport);
sender.send(ret);
} catch (Exception e) {
throw new IllegalAccessError(e.getMessage());
}
}
客户端向服务器端发起的请求真正处理的逻辑在这个方法里面,这个方法在处理完调用了相应的服务端handler进行响应后,会将需要返回给客户端的信息封装在transport这个对象然后传递出去,这个对象是封装服务器和客户端通信消息的。
那么Transport这个类定义了些什么内容呢
Java代码 收藏代码
public final class Transport implements Serializable {
private static final long serialVersionUID = 1675991188209117209L;
private String clazz;
private String method;
private Object message;
private String key;
clazz是要调用的handler的注解名,method是要调用的方法的注解名,message是封装通信消息的,key代表一个token,客户端将这个token发给服务器端,服务器端根据这个token进行查找,最后将token和处理结果一起返回给客户端。
ok,处理服务端信息的handler看完了,我们再来看看客户端的
Java代码 收藏代码
public abstract class ChannelClientHandler extends SimpleChannelUpstreamHandler {
private final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelClientHandler.class);
public final Map<String, ResultHandler> ret = new ConcurrentHashMap<String, ResultHandler>();
protected abstract void processor(Channel channel, Object message);
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
processor(ctx.getChannel(), e.getMessage());
}
}
ret是封装服务器端返回结果的,它的子类负责实现processor方法。
子类代码如下
Java代码 收藏代码
@Override
protected void processor(Channel channel, Object message) {
Transport t = (Transport) message;
String key = t.getClazz() + t.getMethod() + t.getKey();
ResultHandler r = ret.remove(key);
r.processor(t.getMessage());
}
ResultHandler这个是我定义的一个接口,专门处理异步返回的结果,可以通过匿名函数调用
Java代码 收藏代码
public interface ResultHandler<T> {
public void processor(T message);
}
上面说了如何处理netty内部的异步机制,让主线程能够等待异步返回的结果
处理代码如下
Java代码 收藏代码
public Object get(String url, Object... params) {
class Result {
public Object o;
}
final Result ret = new Result();
synchronized (ret) {
try {
invoke(url, params, new ResultHandler() {
@Override
public void processor(Object message) {
synchronized (ret) {
ret.o = message;
ret.notify();
}
}
});
ret.wait();
} catch (InterruptedException e) {
}
return ret.o;
}
}
当客户端调用get方法时候,就可以得到服务器端异步返回的结果了。但是对客户端来说,他感觉到的是同步的调用。
最后我定义了一个InvokeHandler,当开发者开发服务端程序时候,需要实现这个接口,定义自己的handler
类似如下
Java代码 收藏代码
@Handler(name="testhandler")
public class Server1 implements InvokeHandler
{
@Remote(url="test2")
public String say(String msg) {
System.out.println(msg);
return "hi";
}
@Remote(url= "test2")
public String say2(Person p) {
System.out.println(p.getId());
return p.getName();
}
}
上面定义的这些注解,在WSCFInit初始化的时候会放到一个map里面,类似于spring的配置文件。
最后再说说客户端是怎么调用的,在连接好服务端ip和port后,通过如下调用方式就可以了
Java代码 收藏代码
public class Client {
private static ClientSender sender;
public static void main(String[] args) {
sender = ClientProxy.connect(ip, port);
Object msg = sender.get("tcp://testhandler/test1", "hello");
System.out.println(msg);
Person p = new Person();
p.setId(1);
p.setName("zhangsan");
Object o = sender.get("tcp://testhandler/test2", p);
System.out.println(o);
}
}
这样就ok了,也可以自定义要传输的是对象还是xml还是json。同时可以方便的定义自己的解码器。完成自己的业务需求。
接上文,这个服务是基于netty的,每connect一次,就会在服务器上建立一个tcp连接,就是一对pipe,如果不及时释放,那么建立的pipe会越来越多,严重浪费服务器的资源。但是如果释放了,就失去了tcp长连接的作用了。所以折中一下,为了减少连接数,保证客户端的固定连接,服务端不变,在客户端加入连接池功能。
Java代码 收藏代码
public synchronized ClientSender getClientSender() {
Channel channel = getChannel();
if(!channel.isOpen()) {
connectPool.remove(channel);
channel = createConnect(address, port);
connectPool.addLast(channel);
}
return new ClientSender(channel, handler.ret, this);
}
ok,这样就可以用到连接池功能了。每个客户端可以用到固定连接数了。
那么客户端调用的时候需要自己动手创建ConnectPool了
Java代码 收藏代码
public class ClientProxy {
private static ConnectPool pool = null;
public static void connect(String address, int port) {
if (pool == null) {
synchronized (ClientProxy.class) {
if (pool == null) {
pool = ConnectPool.createProxy(address, port);
}
}
}
}
public static Object get(String url, Object... params) {
if(pool == null) {
throw new IllegalStateException("must invoke connect method first");
}
ClientSender sender = pool.getClientSender();
Object msg = sender.get(url, params);
sender.free(); //归还连接
return msg;
}
}
调用方式就不再是上面那样了,要如下调用:
Java代码 收藏代码
ClientProxy.connect(ip, port);
Person p = new Person();
p.setId(12);
p.setName("zhangsan");
Object msg = ClientProxy.get("tcp://server/test1", p);
System.out.println(msg);
来看下控制台
Java代码 收藏代码
Jun 19, 2012 3:24:06 PM com.qunar.wscf.pool.ConnectPool
INFO: 当前连接池中连接数量:5
Jun 19, 2012 3:24:06 PM com.qunar.wscf.pool.ConnectPool
INFO: 连接池中剩余连接数量:4
zhangsan
上次加了连接池功能,后来又提出了一个需求,就是,原来是主线程一直在等待异步线程返回,如果没有返回,主线程就阻塞了,进行不下去。后来发现这个太受限制了。主线程可以先边做自己的事情边等待异步线程处理,符合nio的事件处理机制。于是基于上一点,改造成基于异步的同步。
Java代码 收藏代码
private static class Result {
Object obj;
}
final Result f = new Result();
private volatile boolean hasNotified = false; //异步线程是否结束的标志
public void preGet(String url, Object... params) {
invoke(url, params, new ResultHandler() {
@Override
public void processor(Object message) {
synchronized (f) {
f.obj = message;
f.notify(); //异步线程结束,唤醒客户端线程
hasNotified = true;
}
}
});
}
public Object get() {
synchronized (f) {
if (!hasNotified) //如果异步线程没有结束,则客户端线程等待
try {
f.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
free(); // 释放连接
return f.obj;
}
测试如下:
Java代码 收藏代码
ClientProxy.connect(ip, port);
Person p = new Person();
p.setId(12);
p.setName("zhangsan");
Future future = ClientProxy.get("tcp://server/test1", p);
String str = "hello "; //主线程继续做自己的事情,边做边等待异步返回
System.out.println(str + future.get());
最后打印结果
Java代码 收藏代码
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 当前连接池中连接数量:5
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 连接池中剩余连接数量:4
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 归还连接后连接池中连接的数量:5
hello zhangsan
还有一种情况,主线程等待一段时间后,在规定时间内没有返回,主线程就不等待了。
所以代码改造下,加入超时功能
Java代码 收藏代码
public Object get() {
return get(0);
}
public Object get(long timeout) {
synchronized (f) {
if (!hasNotified)
try {
f.wait(timeout); //主线程等待一定时间
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
free(); // 释放连接
return f.obj;
}
客户端调用,比如1个毫秒没返回,就不再等待了,主线程可以自行处理。
但是又有一个问题,调用的兄弟需要在web中请求这种tcp服务,netty内部是异步处理机制,http是伪长连接,调用结束后,异步请求还没有返回,http连接就断开了,返回的是null。所以这个问题要解决一下。
下面说下封装的各个类的代码吧
首先当客户端对远程服务器发起tcp请求时,这时候请求一般会到达服务器端的handler里,我写的这个handler继承了netty的SimpleChannelUpstreamHandler,代码如下:
Java代码 收藏代码
public abstract class ChannelServerHandler extends SimpleChannelUpstreamHandler {
private final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelServerHandler.class);
protected final Map<String, InvokeHandler> handlers = new HashMap<String, InvokeHandler>();
protected final Map<String, Method> initMethods = new HashMap<String, Method>();
public ChannelServerHandler() {
WSCFInit.register(handlers, initMethods);
}
protected abstract void processor(Channel channel, Object message);
@Override
public final void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Transport t = (Transport) e.getMessage();
String className = t.getClazz();
String methodName = t.getMethod();
logger.info("Invoke Handler:" + className + ", Invoke Method:" + methodName);
processor(ctx.getChannel(), t);
}
里面有几个变量需要解释一下,handlers是开发tcp服务端的handler存放的map,initMethods是里面需要调用的方法,通过WSCFInit类来进行初始化工作。
它主要做了如下工作,在服务器端Server启动的时候,扫描固定包下的handler和他们的方法,然后以clazz+method的方式存放在handlers和initMthods这两个map中。
Java代码 收藏代码
Reflections reflections = new Reflections("packagename");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith((Class<? extends Annotation>) annClass);
Iterator<Class<?>> it = annotated.iterator();
while (it.hasNext()) {
Class<?> next = it.next();
if (next.isAnnotationPresent(Handler.class)) {
Annotation ann = (Annotation) next.getAnnotation((Class<? extends Annotation>) annClass);
handlers.put(((Handler) ann).name(), (InvokeHandler) next.newInstance());
Method[] methods = next.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Remote.class)) {
Remote path = method.getAnnotation(Remote.class);
initMethods.put(((Handler) ann).name() + path.url(), method);
}
}
}
}
protected abstract void processor(Channel channel, Object message);这个方法具体的逻辑是由它的子类来处理的。
再看一下ServerHandler类里面processor的代码,这个类继承了ChannelServerHandler
Java代码 收藏代码
@Override
protected void processor(Channel channel, Object message) {
Transport transport = (Transport) message;
InvokeHandler handler = handlers.get(transport.getClazz());
Object[] params = (Object[]) transport.getMessage();
Object ret = null;
try {
Method method = initMethods.get(transport.getClazz() + transport.getMethod());
if (method == null) {
} else {
ret = method.invoke(handler, params);
}
ServerSender sender = new ServerSender(channel, transport);
sender.send(ret);
} catch (Exception e) {
throw new IllegalAccessError(e.getMessage());
}
}
客户端向服务器端发起的请求真正处理的逻辑在这个方法里面,这个方法在处理完调用了相应的服务端handler进行响应后,会将需要返回给客户端的信息封装在transport这个对象然后传递出去,这个对象是封装服务器和客户端通信消息的。
那么Transport这个类定义了些什么内容呢
Java代码 收藏代码
public final class Transport implements Serializable {
private static final long serialVersionUID = 1675991188209117209L;
private String clazz;
private String method;
private Object message;
private String key;
clazz是要调用的handler的注解名,method是要调用的方法的注解名,message是封装通信消息的,key代表一个token,客户端将这个token发给服务器端,服务器端根据这个token进行查找,最后将token和处理结果一起返回给客户端。
ok,处理服务端信息的handler看完了,我们再来看看客户端的
Java代码 收藏代码
public abstract class ChannelClientHandler extends SimpleChannelUpstreamHandler {
private final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelClientHandler.class);
public final Map<String, ResultHandler> ret = new ConcurrentHashMap<String, ResultHandler>();
protected abstract void processor(Channel channel, Object message);
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
processor(ctx.getChannel(), e.getMessage());
}
}
ret是封装服务器端返回结果的,它的子类负责实现processor方法。
子类代码如下
Java代码 收藏代码
@Override
protected void processor(Channel channel, Object message) {
Transport t = (Transport) message;
String key = t.getClazz() + t.getMethod() + t.getKey();
ResultHandler r = ret.remove(key);
r.processor(t.getMessage());
}
ResultHandler这个是我定义的一个接口,专门处理异步返回的结果,可以通过匿名函数调用
Java代码 收藏代码
public interface ResultHandler<T> {
public void processor(T message);
}
上面说了如何处理netty内部的异步机制,让主线程能够等待异步返回的结果
处理代码如下
Java代码 收藏代码
public Object get(String url, Object... params) {
class Result {
public Object o;
}
final Result ret = new Result();
synchronized (ret) {
try {
invoke(url, params, new ResultHandler() {
@Override
public void processor(Object message) {
synchronized (ret) {
ret.o = message;
ret.notify();
}
}
});
ret.wait();
} catch (InterruptedException e) {
}
return ret.o;
}
}
当客户端调用get方法时候,就可以得到服务器端异步返回的结果了。但是对客户端来说,他感觉到的是同步的调用。
最后我定义了一个InvokeHandler,当开发者开发服务端程序时候,需要实现这个接口,定义自己的handler
类似如下
Java代码 收藏代码
@Handler(name="testhandler")
public class Server1 implements InvokeHandler
{
@Remote(url="test2")
public String say(String msg) {
System.out.println(msg);
return "hi";
}
@Remote(url= "test2")
public String say2(Person p) {
System.out.println(p.getId());
return p.getName();
}
}
上面定义的这些注解,在WSCFInit初始化的时候会放到一个map里面,类似于spring的配置文件。
最后再说说客户端是怎么调用的,在连接好服务端ip和port后,通过如下调用方式就可以了
Java代码 收藏代码
public class Client {
private static ClientSender sender;
public static void main(String[] args) {
sender = ClientProxy.connect(ip, port);
Object msg = sender.get("tcp://testhandler/test1", "hello");
System.out.println(msg);
Person p = new Person();
p.setId(1);
p.setName("zhangsan");
Object o = sender.get("tcp://testhandler/test2", p);
System.out.println(o);
}
}
这样就ok了,也可以自定义要传输的是对象还是xml还是json。同时可以方便的定义自己的解码器。完成自己的业务需求。
接上文,这个服务是基于netty的,每connect一次,就会在服务器上建立一个tcp连接,就是一对pipe,如果不及时释放,那么建立的pipe会越来越多,严重浪费服务器的资源。但是如果释放了,就失去了tcp长连接的作用了。所以折中一下,为了减少连接数,保证客户端的固定连接,服务端不变,在客户端加入连接池功能。
Java代码 收藏代码
public synchronized ClientSender getClientSender() {
Channel channel = getChannel();
if(!channel.isOpen()) {
connectPool.remove(channel);
channel = createConnect(address, port);
connectPool.addLast(channel);
}
return new ClientSender(channel, handler.ret, this);
}
ok,这样就可以用到连接池功能了。每个客户端可以用到固定连接数了。
那么客户端调用的时候需要自己动手创建ConnectPool了
Java代码 收藏代码
public class ClientProxy {
private static ConnectPool pool = null;
public static void connect(String address, int port) {
if (pool == null) {
synchronized (ClientProxy.class) {
if (pool == null) {
pool = ConnectPool.createProxy(address, port);
}
}
}
}
public static Object get(String url, Object... params) {
if(pool == null) {
throw new IllegalStateException("must invoke connect method first");
}
ClientSender sender = pool.getClientSender();
Object msg = sender.get(url, params);
sender.free(); //归还连接
return msg;
}
}
调用方式就不再是上面那样了,要如下调用:
Java代码 收藏代码
ClientProxy.connect(ip, port);
Person p = new Person();
p.setId(12);
p.setName("zhangsan");
Object msg = ClientProxy.get("tcp://server/test1", p);
System.out.println(msg);
来看下控制台
Java代码 收藏代码
Jun 19, 2012 3:24:06 PM com.qunar.wscf.pool.ConnectPool
INFO: 当前连接池中连接数量:5
Jun 19, 2012 3:24:06 PM com.qunar.wscf.pool.ConnectPool
INFO: 连接池中剩余连接数量:4
zhangsan
上次加了连接池功能,后来又提出了一个需求,就是,原来是主线程一直在等待异步线程返回,如果没有返回,主线程就阻塞了,进行不下去。后来发现这个太受限制了。主线程可以先边做自己的事情边等待异步线程处理,符合nio的事件处理机制。于是基于上一点,改造成基于异步的同步。
Java代码 收藏代码
private static class Result {
Object obj;
}
final Result f = new Result();
private volatile boolean hasNotified = false; //异步线程是否结束的标志
public void preGet(String url, Object... params) {
invoke(url, params, new ResultHandler() {
@Override
public void processor(Object message) {
synchronized (f) {
f.obj = message;
f.notify(); //异步线程结束,唤醒客户端线程
hasNotified = true;
}
}
});
}
public Object get() {
synchronized (f) {
if (!hasNotified) //如果异步线程没有结束,则客户端线程等待
try {
f.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
free(); // 释放连接
return f.obj;
}
测试如下:
Java代码 收藏代码
ClientProxy.connect(ip, port);
Person p = new Person();
p.setId(12);
p.setName("zhangsan");
Future future = ClientProxy.get("tcp://server/test1", p);
String str = "hello "; //主线程继续做自己的事情,边做边等待异步返回
System.out.println(str + future.get());
最后打印结果
Java代码 收藏代码
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 当前连接池中连接数量:5
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 连接池中剩余连接数量:4
Jun 20, 2012 2:26:12 PM com.qunar.wscf.pool.ConnectPool
INFO: 归还连接后连接池中连接的数量:5
hello zhangsan
还有一种情况,主线程等待一段时间后,在规定时间内没有返回,主线程就不等待了。
所以代码改造下,加入超时功能
Java代码 收藏代码
public Object get() {
return get(0);
}
public Object get(long timeout) {
synchronized (f) {
if (!hasNotified)
try {
f.wait(timeout); //主线程等待一定时间
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
free(); // 释放连接
return f.obj;
}
客户端调用,比如1个毫秒没返回,就不再等待了,主线程可以自行处理。
相关推荐
在Android开发中,为了实现高效的网络通信,开发者常常会选择使用Netty框架。Netty是一个高性能、异步事件驱动的网络应用程序框架,适用于多种协议的服务器和客户端应用。本篇文章将详细探讨如何在Android环境中利用...
基于Netty框架的网络通信项目 项目简介 本项目是一个基于Netty框架的网络通信项目,涵盖了多种网络通信场景和功能实现。Netty是一个高性能、异步事件驱动的网络应用框架,广泛用于构建高性能的网络服务器和客户端...
基于Netty框架的网络通信示例 内容概要 本项目是一个基于Netty框架的网络通信示例,涵盖了多种网络通信场景,包括TCP、UDP、WebSocket等。项目展示了如何使用Netty进行高性能的异步网络编程,并提供了丰富的示例...
SOFABolt 是蚂蚁金融服务集团开发的一套基于 Netty 实现的网络通信框架。为了让 Java 程序员能将更多的精力放在基于网络通信的业务逻辑实现上,而不是过多的纠结于网络底层 NIO 的实现以及处理难以调试的网络问题,...
# 基于Netty框架的网络通信系统 ## 项目简介 本项目是一个基于Netty框架的网络通信系统,涵盖了多种网络通信场景和协议,包括TCP、UDP、HTTP、WebSocket等。通过使用Netty的高性能异步事件驱动框架,实现了高效、...
本资源提供了一套基于Netty的蚂蚁集团网络通信框架SOFABolt的设计源码,包含326个文件,其中包括288个Java源代码文件,9个XML配置文件,8个Markdown文档,3个YAML配置文件,以及3个PNG图片文件。此外,还包括2个...
SOFABolt是蚂蚁金融服务集团开发的一款网络通信框架,其核心是基于Netty构建的。Netty是一个异步事件驱动的网络应用框架,专为高性能、低延迟的网络应用设计,广泛应用于金融、互联网等领域。SOFABolt的设计理念是轻...
在本项目中,我们将基于Netty实现一个手写的RPC框架。Netty是Java领域的一个高性能、异步事件驱动的网络应用程序框架,常用于构建高效的服务器和客户端。 首先,我们需要理解RPC框架的基本组成部分: 1. **服务...
SOFABolt 是蚂蚁金融服务集团开发的一套基于 Netty 实现的网络通信框架。为了让 Java 程序员能将更多的精力放在基于网络通信的业务逻辑实现上,而不是过多的纠结于网络底层 NIO 的实现以及处理难以调试的网络问题,...
本项目“基于Netty的即时通信”旨在演示如何利用Netty构建一个简单的聊天应用,它包括服务端和客户端,实现了多客户端之间的实时交互,并且聊天界面设计模仿了QQ或微信的界面风格。 首先,我们要理解Netty的核心...
Netty4+ProtoBuf通信框架是一种高效的网络应用框架,它结合了Netty的高性能和Google的Protocol Buffers(ProtoBuf)的数据序列化能力,用于构建可伸缩、高并发的网络应用程序。在这个项目中,客户端和服务端之间的...
本项目是基于Netty 4.0实现的自定义RPC通信框架,旨在为Java开发者提供一种高效、灵活的远程服务调用解决方案。 首先,我们来深入理解Netty的基本概念。Netty的核心是其NIO(非阻塞I/O)模型,它使用了Reactor模式...
在Android开发中,网络通信是不可或缺的一部分,而Netty是一个高效、强大的网络应用程序框架,它为构建高性能、稳定的网络服务器提供了便利。本示例“Android-netty和socket通信的demo”将展示如何在Android平台上...
基于Netty的高性能RPC框架 项目概述 NettyRPC是一个基于Netty构建的高性能Java RPC服务器,支持多种消息序列化方式,如Kryo、Hessian和Protostuff。该项目通过Spring容器管理服务定义和实现,采用主从Reactor线程...
- **异常处理**:确保有适当的错误处理机制,当业务逻辑或网络通信出错时,能提供友好的错误信息。 - **拦截器**:SpringMVC中的拦截器可以用来进行权限检查、日志记录等操作。在Netty中,可以实现类似的过滤器链。...
本文将深入探讨一个基于Netty的Java数据采集软件,它利用Netty强大的网络通信框架,实现了对大规模分布式数据节点的高效采集。 Netty是一个高性能、异步事件驱动的网络应用程序框架,广泛应用于服务器开发,特别是...
Netty是一个高性能、异步事件驱动的网络应用框架,它为Java开发人员提供了构建高性能、稳定、可扩展的网络服务器和...通过学习和理解这个Demo,可以深入掌握Netty在移动平台上的应用,提升Android应用的网络通信能力。