ios apns java codec 防止粘包

 public Bootstrap newBootstrap(Bootstrap bootstrap,final PushHandler phandler) {bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();if (isSsl) {SSLContext sslContext = SSLUtil.initSSLContext(credentials.getCertification(), credentials.getPassword());SSLEngine sslEngine = sslContext.createSSLEngine();sslEngine.setUseClientMode(true);pipeline.addLast("ssl", new SslHandler(sslEngine));}if (Constant.debug) {pipeline.addLast("log", new LoggingHandler(LogLevel.DEBUG));}pipeline.addLast("encoder", new Encoder());pipeline.addLast("decoder", new Decoder());pipeline.addLast("pushHandler", phandler);}});return bootstrap;}
package com.couriusby.apns.codec;import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.curiousby.apns.message.ErrorResponse;public class Decoder extends ByteToMessageDecoder
{static final Logger logger = LoggerFactory.getLogger(Decoder.class);// 据文档: command + status + identifier = 1 + 1 + 4static final int responseSize = 6;@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception{// logger.debug("readableBytes:" + in.readableBytes());if (in.readableBytes() >= responseSize){ErrorResponse errorResponse = new ErrorResponse();errorResponse.setCommond(in.readByte());errorResponse.setStatus(in.readByte());errorResponse.setIdentifier(in.readInt());errorResponse.setErrorMsg(ErrorResponse.getErrorMsgByStatus(errorResponse.getStatus()));out.add(errorResponse);}logger.debug("decoder:" + out);}
}
package com.curiousby.apns.codec;import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;import java.nio.charset.Charset;
import java.util.Date;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.curiousby.apns.message.Item;
import com.curiousby.apns.message.Notification;/*** <pre>* 1 byte      4 byte * command + frameLength + item + item + ... + item* *         1 byte     2 byte * item = itemId + itemLength + itemData* * itemData据不同的类型有不同的长度:* * </pre>* * 采用组发送的方式,一次发送一系列的消息,然后每个消息的notificationIdentifier都是连续的,* 这样,如果apple的服务器返回错误,那么可以从错误里的Identifier知道是哪个出错了,然后重发下面的消息。*/
public class Encoder extends MessageToByteEncoder<Notification>
{static final Logger logger = LoggerFactory.getLogger(Encoder.class);// TODO 这个到底要不要做成static的,static的可能容易调试点,不然每个线程都有一个计数的话,可能会比较乱// TODO 处理超出int范围,再重新从0开始的逻辑int identifier = 0;static final Charset utf8 = Charset.forName("UTF-8");// 据apple的文档,这个值就是2,据其它地方看到的资料,有0和1的版本。static final int COMMAND = 2;static final int defaultExpirationDate = 0;@Overrideprotected void encode(ChannelHandlerContext ctx, Notification notification, ByteBuf out) throws Exception{// logger.debug("NotificationEncoder:" + notification);// String data =// "02000000770100205CA6A718250E1868A8EB7D8964D3E8A051B009268A3D710D0D8CC6591572890802003F7B22617073223A7B22736F756E64223A2264656661756C74222C22616C657274223A2252696E672072696E672C204E656F2E222C226261646765223A317D7D030004000000650400047FFFFFFF0500010A";// out.writeBytes(Hex.decodeHex(data.toCharArray()));out.writeByte(COMMAND);out.writeInt(0); // 预先写入frameLenint frameLenIndex = out.writerIndex();// 这里不检验数据格式的正确性,上层要检查// 开始写入items// 开始写入Device tokenout.writeByte(Item.DEVICE_TOKEN);out.writeShort(32);out.writeBytes(notification.getToken());// 写入Payloadout.writeByte(Item.PAYLOAD);out.writeShort(notification.getPayload().length);out.writeBytes(notification.getPayload());// 写入Notification identifierout.writeByte(Item.NOTIFICATION_IDENTIFIER);out.writeShort(4);out.writeInt(notification.getId());// 写入Expiration dateout.writeByte(Item.EXPIRATION_DATE);out.writeShort(4);Date expirationDate = notification.getExpirationDate();if (expirationDate == null){out.writeInt(0);}else{out.writeInt((int) (expirationDate.getTime() / 1000));}// 写入Priorityout.writeByte(Item.PRIORITY);out.writeShort(1);out.writeByte(notification.getPriority());// 回退到该写入frameLen的位置,写入frameLen,再重新设置write indexint currentWriteIndex = out.writerIndex();out.writerIndex(1); // 因为command后面就是len,而command是1 byte。out.writeInt(currentWriteIndex - frameLenIndex);out.writerIndex(currentWriteIndex);}
}

捐助开发者

在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信捐助,加入it技术扣扣群),没钱捧个人场,谢谢各位。


 
 
 谢谢您的赞助,我会做的更好!

ios apns netty java codec 防止粘包相关推荐

  1. Java NIO 框架 Netty 之美:粘包与半包问题

    Netty 是一个可以快速开发网络应用程序的 NIO 框架,它大大简化了 TCP 或者 UDP 服务器的网络编程.Netty 的简易和快速开发并不意味着由它开发的程序将失去可维护性或者存在性能问题,它 ...

  2. Netty解决TCP的粘包和分包(二)

    2019独角兽企业重金招聘Python工程师标准>>> Netty解决TCP的粘包和分包(二) 使用LengthFieldBasedFrameDecoder解码器分包 先看一下这个类 ...

  3. Netty是如何解决粘包和拆包问题的

    本文来说下Netty是如何解决粘包和拆包问题的 文章目录 概述 粘包和拆包 常见解决方案 Netty提供的粘包拆包解决方案 FixedLengthFrameDecoder LineBasedFrame ...

  4. Netty框架之TCP粘包/半包解决方案

    Netty框架之TCP粘包/半包解决方案 一.TCP粘包 二.TCP半包 三.TCP粘包/半包解决方案 1.FixedLengthFrameDecoder定长解析器 2.LineBasedFrameD ...

  5. netty半包粘包 处理_Java NIO 框架 Netty 之美:粘包与半包问题

    一.前言 Netty 是一个可以快速开发网络应用程序的 NIO 框架,它大大简化了 TCP 或者 UDP 服务器的网络编程.Netty 的简易和快速开发并不意味着由它开发的程序将失去可维护性或者存在性 ...

  6. Netty编解码,粘包拆包及零拷贝

    Netty编解码 Netty涉及到编解码的组件有Channel.ChannelHandler.ChannelPipe等,先大概了解下这几个组件的作用. ChannelHandler ChannelHa ...

  7. 深入理解Netty编解码、粘包拆包、心跳机制

    点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章. 本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 BIO .NIO .AIO 总 ...

  8. 面试官问:你来讲下Netty通信中的粘包、拆包?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Java技术剑 来源:https://urlify.cn/I ...

  9. 【Netty入门】TCP 粘包/拆包问题产生原因

    TCP粘包/分包问题的由来 因为TCP是以流的方式来处理数据,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送. 这样说可能比较抽象,下面举例来说明TCP拆包/粘包 ...

最新文章

  1. docker(3)docker下的centos7下安装jdk
  2. Inception SQL审核注解
  3. javascript的promise
  4. R语言:plot()函数参数合集
  5. IP地址与网络上的其他系统有冲突
  6. uva 1203—— Argus
  7. Jenkins修改管理员密码
  8. 使用Uchihash处理恶意软件中的嵌入式哈希
  9. 图算法在反欺诈中的应用
  10. Jenkins插件Gerrit Trigger配置,实现change-merged时自动触发Jenkins工程build
  11. 电脑录屏怎么录?3个方法,教你如何录制视频
  12. gmx grompp
  13. SVN提交报错 Attempted to lock an already-locked dir
  14. js 跳转到指定位置 高德地图_第三方高德地图Javascript API
  15. bootstrap轮播速度_BootStrap:轮播插件
  16. 浅谈Openstack网络原理(openstack无法上网?)
  17. 赏析:滕王阁序(唐代:王勃)
  18. 20172303 20172322 2017-2018-2 暑假作业 结对编程项目-舒尔特方格(增补:计时器的加入与页面优化)...
  19. quartz学习笔记7:trading
  20. RPC实现和原理解析

热门文章

  1. 限制会话id服务端不共享_【干货分享】Web安全漏洞深入分析及其安全编码
  2. 计算机继续教育笔记,《继续教育中的学习技术》读书笔记
  3. mysql存储过程实例实现查询_Mybatis应用mysql存储过程查询数据实例
  4. Cookie和Session的知识
  5. 不要在循环,条件或嵌套函数中调用 Hook
  6. JavaScript 代码片段
  7. java的响应机制_JAVA事件响应机制
  8. mysql unescape解码_python mysql escape\n(简单语法错误)
  9. matlab中garchred是什么意思,MATLAB里的aic是啥意思
  10. css 垂直居中_CSS垂直居中的另类实现