Git Product home page Git Product logo

rhsocketkit's Introduction

RHSocketKit

Build Status Version Status Analytics Platform License

socket网络通信框架

虽然CocoaAsyncSocket已经非常的成熟,但是项目,业务,协议等不同导致tcp模块的公用性不高,需要根据协议重新订制调整,不能直接拷贝框架使用。 为了减少调整消耗的时间,对tcp模块中相关的内容进行拆分实现。

功能简介

  • TCP支持缓存拼包功能
  • 支持快速实现自定义编码解码
  • 默认支持分隔符编解码、可变长度编解码、protobuf基础通信编解码
  • 支持发送数据包内存级缓存
  • 支持心跳设置,快速自定义
  • 支持TCP自动重连
  • TCP链接支持1对多观察者
  • 通信底层增加interceptor拦截器,方便数据观察及其他自定义扩展

其中专为和netty通信互通而实现了3个主要编解码器:

  • 1 分隔符编解码:RHSocketDelimiterDecoder, RHSocketDelimiterEncoder
  • 2 可变长度编解码:RHSocketVariableLengthDecoder, RHSocketVariableLengthEncoder
  • 3 protobuf通信编解码:RHProtobufVarint32LengthDecoder, RHProtobufVarint32LengthEncoder

工程Demo迁移

Example工程较久未维护,计划废弃;目前代码已经迁移到Pipeline目录下的Pipeline工程中,想要学习了解的同学可以直接跑Pipeline工程;

进入到Pipeline目录,然后只想 pod install 命令

如果在Xcode10中出现如下错误提升:

Multiple commands produce '/Users/zhuruhong/Library/Developer/Xcode/DerivedData/Pipeline-hfoiorbrhlstyohibtuanawzieym/Build/Products/Debug-iphonesimulator/Pipeline.app':

  1. Target 'Pipeline' has create directory command with output '/Users/zhuruhong/Library/Developer/Xcode/DerivedData/Pipeline-hfoiorbrhlstyohibtuanawzieym/Build/Products/Debug-iphonesimulator/Pipeline.app'

  2. That command depends on command in Target 'Pipeline': script phase "[CP] Copy Pods Resources"

请按照下面方法解决:

  1. In Xcode, go to File->Project/Workspace settings.

  2. Change the build system to Legacy Build system.

CocoaPods

pod 'RHSocketKit'

Features Log

框架的设计运用了一些设计模式,通过组合和协议编程,灵活多变,扩展方便。

目前框架的核心在core目录中,主要组件有connection,channel,packet,codec,exception,utils,其中codec的实现是业务重点。

另外,RHSocketService是一个单例实现,方便直接调用。RPC是一个深度封装的内容,需要理解框架才能使用。

image


RHSocketConnection

socket网络连接对象,只负责socket网络的连接通信,内部使用GCDAsyncSocket。
1-只公开GCDAsyncSocket的主要方法,增加使用的便捷性。
2-封装的另一个目的是,易于后续更新调整。如果不想使用GCDAsyncSocket,只想修改内部实现即可,对外不产生影响。

RHSocketChannel

在RHSocketConnection基础上做封装,负责对socket中的二进制通讯数据做缓存、粘包,内部需要编码、解码处理。
1-需要有一个编码解码器,对数据块做封包和解包。很多人不理解这个,其实很简单。比如一句话里面没有标点符号你怎么知道什么时候是结束什么时候开始呢
2-内部带有一个数据缓存,用于对数据的拼包。发送网络数据时,一条数据会被切成多个网络包[不是我们上层协议中的概念],需要对收到的数据做合并,完整后才能正常解码。

Packet-数据包协议

/**
 *  数据包协议
 */
@protocol RHSocketPacket <NSObject>

@required

/**
 *  数据包携带的数据变量(可以是任何数据格式)
 */
@property (nonatomic, strong) id object;

@optional

/**
 *  类似tag,必要的时候实现,用于区分某个数据包
 */
@property (nonatomic, assign) NSInteger pid;

- (instancetype)initWithObject:(id)aObject;

@end
/**
 *  上行数据包协议,发送数据时,必须遵循的协议
 */
@protocol RHUpstreamPacket <RHSocketPacket>

@optional

/**
 *  发送数据超时时间,必须设置。-1时为无限等待
 */
@property (nonatomic, assign) NSTimeInterval timeout;

@end
/**
 *  下行数据包协议,接收数据时,必须遵循的协议
 */
@protocol RHDownstreamPacket <RHSocketPacket>

@end

Codec-编码器encoder和解码器decoder

编码器和解码器是应用传输协议直接相关的重点,简单的有:

  • 分隔符编码器RHSocketDelimiterEncoder和解码器RHSocketDelimiterDecoder。
  • 可变长度编码器RHSocketVariableLengthEncoder和解码器RHSocketVariableLengthDecoder。

为了保证数据安全,一般都会在协议上做一些特殊定义,防止被恶意访问,所以自定义协议是必须的。框架的编码和解码协议如下,可以自由实现,满足需求。demo可以查看RHSocketCustomCodecDemo和基于本框架的RHMQTTKit。

/**
 *  编码器协议
 */
@protocol RHSocketEncoderProtocol <NSObject>

@required

/**
 *  编码器
 *
 *  @param packet 待发送的数据包
 *  @param output 数据编码后,分发对象
 */
- (void)encode:(id<RHUpstreamPacket>)upstreamPacket output:(id<RHSocketEncoderOutputProtocol>)output;

@end
/**
 *  解码器协议
 */
@protocol RHSocketDecoderProtocol <NSObject>

/**
 *  解码器
 *
 *  @param downstreamPacket 接收到的原始数据
 *  @param output           数据解码后,分发对象
 *
 *  @return -1解码异常,断开连接; 0数据不完整,等待数据包; >0解码正常,为已解码数据长度
 */
- (NSInteger)decode:(id<RHDownstreamPacket>)downstreamPacket output:(id<RHSocketDecoderOutputProtocol>)output;

@end

Issue

  • [感谢snilwx的反馈] 数据缓存过大的控制问题:在RHSocketChannel的didRead:withData:tag:方法中,若网络积压,造成多个数据包拼接,一次性读取到大量数据,超过最大值maxFrameSize设置时,会直接断开链接,会造成当前链接的数据接收没有被正常处理。缓存接收到的数据大小,由缓存模块做逻辑控制更加合理,解码器只需要关心解码是否正常。若缓存超过缓存区最大值,则可以按照缓存模块的分块逻辑,对整块缓存做分块切割,然后按次丢给解码器处理

  • 上行数据缓存、重发:发送失败数据重发,包括未连接时发送数据包,发送失败数据包

  • 下行数据缓存:下行数据包缓存,处理拼包、粘包问题

  • 数据测试demo:在app内闭环数据测试逻辑,包括不同的编码器、解码器逻辑

  • SDK被集成统计:缺少被集成数据统计逻辑,增加简单控制,参考lookin




联系方式

qq: 410289616
email: [email protected]
qq群1: 330585393
qq群2: 371293816
qq群3: 231199626

如果觉得我的源码对您有帮助,请点击starfork
如果您正好有余粮,欢迎随意打赏。
您的奖励是给予我莫大的鼓励和支持!
image

rhsocketkit's People

Contributors

zhu410289616 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rhsocketkit's Issues

看了您的源码,对于超出缓存大小后的处理的疑问

分隔符解码器中maxFrameSize默认是8192,如果接收数据的速度大于解码数据的速度,那么肯定就会在某一时刻出现超出maxFrameSize的情况,这时您的操作是断开连接,但是与此同时没有对_receiveDataBuffer里的数据进行及时的解码处理,那么下次重新连接成功后,_receiveDataBuffer里的数据就只能丢弃,这不符合长连接保证数据的准确性原则。如果解码的时候每次都从缓存中取出固定大小(比如maxFrameSize)解码,给_receiveDataBuffer缓存池设置一个最大的size,超出size后断开连接,但是解码工作一直继续,直到_receiveDataBuffer为空,会不会更好一些?

RHChannelConfig中的delegate并没有使用到

Issue Description

RHChannelConfig中的delegate并没有使用到

What

RHChannelConfig中的delegate并没有使用到,delegate貌似是通过channelService.channel addDelegate方法添加的

关于netty 编码和解码器

你好,关注您的代码很久了,我在开发中遇到一个问题,服务器端用的是netty4 提供的编码器和解码器,服务器部分代码如下
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();

           pipeline.addLast(new ProtobufVarint32FrameDecoder());
            pipeline.addLast(new ProtobufDecoder(PushMgsPaket.IMMessage.getDefaultInstance()));
            pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
            pipeline.addLast(new ProtobufEncoder());

            pipeline.addLast(new TcpServerHandler());  
        }  

那么对应的IOS端有没有对应的编码和解码与之匹配的

错误

  • (uint32_t)uint32FromBytes:(NSData *)data
    {
    NSAssert(data.length == 4, @"uint16FromBytes: (data length != 4)");

    uint32_t val0 = 0;
    uint32_t val1 = 0;
    uint32_t val2 = 0;
    uint32_t val3 = 0;
    [data getBytes:&val0 range:NSMakeRange(0, 1)];
    [data getBytes:&val1 range:NSMakeRange(1, 1)];
    [data getBytes:&val2 range:NSMakeRange(2, 1)];
    [data getBytes:&val3 range:NSMakeRange(3, 1)];

    uint32_t dstVal = (val0 & 0xff) + ((val1 << 8) & 0xff00) + ((val1 << 16) & 0xff0000) + ((val1 << 24) & 0xff000000);
    return dstVal;
    }

dstval 算错了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.