pushy

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

内容简介: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的交互

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

查看所有标签

猜你喜欢:

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

首席产品官1 从新手到行家

首席产品官1 从新手到行家

车马 / 机械工业出版社 / 2018-9-25 / 79

《首席产品官》共2册,旨在为产品新人成长为产品行家,产品白领成长为产品金领,最后成长为首席产品官(CPO)提供产品认知、能力体系、成长方法三个维度的全方位指导。 作者在互联网领域从业近20年,是中国早期的互联网产品经理,曾是周鸿祎旗下“3721”的产品经理,担任CPO和CEO多年。作者将自己多年来的产品经验体系化,锤炼出了“产品人的能力杠铃模型”(简称“杠铃模型”),简洁、直观、兼容性好、实......一起来看看 《首席产品官1 从新手到行家》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具