pushy

栏目: 后端 · 发布时间: 8年前

内容简介:pushy

前言(待整理)

relayrides/pushy 是一个 Java library for sending APNs (iOS, OS X, and Safari) push notifications. 揉和了netty和http2协议。因此,除了它本身的功能外,从中也可以学到许多对netty框架以及http2协议的使用技巧。

对外接口

ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
payloadBuilder.setAlertBody("Example!");
String payload = payloadBuilder.buildWithDefaultMaximumLength();
String token = TokenUtil.sanitizeTokenString("<efc7492 bdbd8209>");
SimpleApnsPushNotification  pushNotification = new SimpleApnsPushNotification(token, "com.example.myApp", payload);
Future<PushNotificationResponse<SimpleApnsPushNotification>> sendNotificationFuture = apnsClient.sendNotification(pushNotification);

从pushy中学到的

既写又读的handler

一般框架Client,通过一个id关联request和response(通过future来获取),这个future要在多个类之间传递。

class Client{
	Map<id,future> map;
	Future<Response> send(request){
		future = new xxx;
		map.put(id,future);
		channel.write(request).addListener(new xx{
			onComplete(){
				xxx
				future.set(xx)
			}
		});
		return future;
	}
}
class ReceiveHandler{
	Map<id,future> map;
	onDataReceive(response){
		future = map.get(response.getId());
		future.set(xx)
	}
}

而pushy则是

class ApnsClient{
	Future<Response> send(request){
		future = new xx();
		channel.write(new Composite(request,future));
		return future;
	}
}

ApnsClientHandler{
	Map<id,future> map;
	write(composite){
		request = composite.getRequest()
		future = composite.getFuture();
		map.put(id,future)
		write(request).addListener(){
			future.set(xx)
		}
	}
	onDataReceive(response){
		future = map.get(response.getId());
		future.set(xx);
	}
}

从代码上讲,write和receive都写在一个类里(这里是),因为write和read要共享很多数据,这些数据作为ApnsClientHandler的成员,代码上就可以更紧凑。

future/promise的转换

这个其实也不是什么技巧,promise是可写的future。

Future operation1(){
	Promise promise = xx
	xxFuture future2 = operation2();
	future2.addListener(new xxListener(){
		onComplete(){
			promise.setxx
		}
	});
	return promise;
}

在本例中,future2并不能直接返回,需要转换成promise(具体的说,通过future2的listener为promise赋值,这也是future/promise这里异步组件特有的转换方式)。一个常见的场景,返回的future要承载某个model,但在获取model之前有几个前置条件

  1. write success,当发送缓冲区拥堵、网络断开时,会write fail
  2. read response success
  3. 如果future承载的model和response model不是一回事,还要根据业务进行语义的转化,这一步也要确保success

也就是说,一个异步操作的结果,可能是多个异步操作结果的叠加。在更复杂的例子中,要为operation2传入promise,介入更深层次的异步操作。可以使用netty的 io.netty.util.concurrent.PromiseCombiner 来简化一些叠加操作。

操作接口

netty对外提供的操作接口有以下几个问题,当然,这也不怨netty

  1. 操作对象有多个,比如bootstrap、channel。并且,操作对象间存在依赖关系,channel不是直接初始化,而是通过bootstrap获得。
  2. 启动逻辑复杂,必须由用户显式编写代码。有的框架本身仅仅业务逻辑,故无需启动(显式调用构造函数、或执行 xx.start() ),比如fastjson。有的本身用到了线程,故需显式启动,比如common-pool。但common-pool的启动逻辑非常简单,netty则较为复杂
  3. 操作接口不简洁,对于io操作,简介的接口应该是

    1. 同步, response send(request)
    2. 异步, Future<response> send(request)

    而netty则无明确封装

维护多次请求的上下文(未完成)

对于client,大部分协议只要求一次请求和响应。而对于http2洗衣,因为使用了 netty-codec-http2 的关系,至少在代码上,

数据的发送分为header和data,那么在header和data之间,便需要维护上下文

其它

当我们有一个新的协议

  1. 像pushy一样,http2协议独立于netty(如何基于netty独立的实现第三方协议,以及这个协议与netty的结合方式),pushy + http2 + netty 组合
  2. 像zk等一样,将netty 作为一个transport层。
model 编解码
业务层 业务model 继承message,实现encode、decode 调用transport层提供的send接口
transport层 message 抽象方法 encode、decode transport 只是实现message的交互

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Vim, Second Edition

Practical Vim, Second Edition

Drew Neil / The Pragmatic Bookshelf / 2015-10-31 / USD 29.00

Vim is a fast and efficient text editor that will make you a faster and more efficient developer. It’s available on almost every OS, and if you master the techniques in this book, you’ll never need an......一起来看看 《Practical Vim, Second Edition》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器