美文网首页iOS开发专题待阅读的文章网络层(socket、Net)
通俗讲解股票类app - TCP网络通信层设计

通俗讲解股票类app - TCP网络通信层设计

作者: ck2016 | 来源:发表于2016-08-24 16:15 被阅读1790次

    场景

    要做的产品 --- 炒股app

    • 数据量大:5000多支股票,每支股票有分时,分笔数据,画一条k线,可能要500条分时数据,甚至更多。
    • 实时性:股价每分每秒都在变化,一分钟产生很多条数据,用户要看到最新的信息,真的是一秒钟上下几十万啊。
    • 服务器主动推:股票预警等等一些重要消息,需要服务器实时推送,保证客户端100%收到,收不到可能造成客户资金损失。

    由于这些场景因素,股票的数据不能通过HTTP协议来传输了,只能走TCP协议了,当然一些个人信息什么的还是走HTTP的。

    技术细节实现

    1.数据量比较大,一次请求可能返回几百条数据到移动端,对数据要进行压缩,这里采用了 google 的 Protocol Buffer 数据传输格式,因为它对象序列化速度快,压缩率高 (ps: http 一般用 json, xml)。

    2.实时性与主动推:服务器与客户端之间维护一条 tcp 长连接,避免每次3次握手,4次挥手,和产生一堆 time_wait 状态的 socket 占用资源。走tcp协议需要自己维护一些状态
    掉线重连,移动端网络情况复杂,有3G,4G,wifi,socket 经常断开,它断了要自动连上,并且还要对应用层透明!不能让应用层感知到!连上后数据接着之前断开的地方发送,不能有影响。
    自动登录,这个是掉线重连后要做的一个操作,不登录拿不到股票数据。登录后接着做一个消息同步,看看有没有新消息。

    3.客户端100%收到(可靠性):除了 tcp 超时重传和3次ack回应保证了可靠传输之外,我们在app里也实现了一套应用层的ack机制,服务器保存了一组消息,每个消息有个seq号,一个消息推给客户端后,客户端拿到消息的seq,要发ack请求回应服务器这个消息,然后下次服务器才不会推给你,不然的话,下次服务器还是会推给你的。掉线重连,重登录后会同步一次你订阅过的消息,把上次没收到的,或者丢包的消息再同步过来。

    4.客户端的负载均衡,这个一般在服务器做,但后台那边说防止ip封锁,还有某些服务器不能在全国访问到,所以把负载均衡放在客户端做了,app启动拉取服务器列表,然后多线程并发发送测速包,得到每个服务器延迟和负载,然后选个最优的服务器连上即可,延迟可以理解为路有多长,负载可以理解为路上拥堵情况,显然最短的路不一定是最快的,它可能很堵。

    根据以上因素,我设计了一套TCP层的网络请求逻辑,应用层只管发请求就好了,我只告诉你有没有结果,上面的细节全部屏蔽在底层,对应用层透明!

    // 应用层发一个 tcp 请求的代码例子,支持多线程循环发:
    [[TCPAPI instance] requestStockInfoWithcompletion:^(id response, NSString *error) {
        if (error == nil) {
            NSLog(@"成功:%@", (NSArray *)response);
        } else {
            NSLog(@"失败:%@", error);
        }
    }];
    

    测试:我用一条线程以每隔 0.1 秒的速度循环发送请求,然后模拟断网,网络差,被服务器踢下线等等情况,程序工作正常,一旦有网络,数据就会成功返回。

    整个app网络层的请求逻辑图:
    我有个 tcp 请求同步队列接收应用层来的请求,有句话叫做"we cannot send directly, so queue it",然后一个请求走完图中的逻辑,下一个请求接着走,每一个请求有一个定时器,超时就回调一个失败结果给应用层,有张映射表保存请求和回调之间的映射。
    然后还一个socket发送队列,真正去发送数据的队列,socket接收队列就不用说了吧,把接收到的数据通过pb协议反序列化得到pb对象的,这里有个 tcp 分片机制导致的 tcp 粘包问题,就是 socket 返回一段二进制数据不一定刚好就是一个对象的全部数据,可能少可能多,要自己判断,拆包的时候注意下就好了。
    得到 pb 对象,把这个结果回调给应用层,整个流程就走完了。

    tcp请求逻辑.png

    图片可能太大,可以到这里下载来看。

    相关文章

      网友评论

      • BeethOven:你怎么会知道这么多知识,佩服:sob:
        ck2016:@龍之逆鳞 什么问题
        龍之逆鳞:您好 我这边也是使用socket和pb 并且做得也是股票类的 想和你具体聊聊 我这边socket已经连接成功 通过pb也拿到数据 不过还有点问题 需要请教一下 您这边方便qq沟通一下? 感激不尽 我的qq:136407260
        ck2016:@放羊的贝多芬呢 请看计算机网络和操作系统

      本文标题:通俗讲解股票类app - TCP网络通信层设计

      本文链接:https://www.haomeiwen.com/subject/wacosttx.html