文档章节

异步转同步

xpbug
 xpbug
发布于 2016/03/02 19:34
字数 875
阅读 171
收藏 3
点赞 1
评论 0

下面是一个CS架构的部署, 服务端是SEDA类型的架构,消息传输完全是异步。而客户端在使用SDK向服务端发起请求。为了方便客户的使用,我们希望能提供同步方式的SDK。所以我们的SDK需要将异步消息转换成同步消息。如何做到这一点呢?

因为服务器需要保持CPU的充分利用,所以异步转同步的工作不应该由Server完成,而应该有SDK来完成。简单的讲,异步转同步的流程应该分成这么几个步骤:

  1. SDK发出请求

  2. SDK等待返回

  3. 服务端持续返回消息

  4. 返回的消息和请求匹配上

  5. SDK返回响应

把以上的步骤封装在SDK里面,上面的示意图可以演变为下面的图

在实现中,requestNo和Waiter是实现的关键。RequestNo使发出的请求和返回的响应能够匹配上,而Waiter则可以使SDK等待,当拿到响应以后,唤醒SDK,返回响应。

略微解释一下上图的流程:

  1. Client调用Sender准备发请求。Sender先生成一个requestNo,将requestNo贴到请求上。然后生成一个waiter,将requestNo和waiter放入Map中。Map中存有所有正在等待消息返回的waiter。然后Sender阻塞在waiter的standby(timeout)方法上。

  2. Sender将消息塞入发送队列。

  3. Connection从发送队列取出消息。

  4. Connection发消息给Server。

  5. Server持续异步返回各类消息。

  6. Connection将返回的消息放入接收队列。

  7. Receiver从接收队里中取出消息。

  8. Receiver从消息中获取requestNo,然后从Map中获取相应的waiter。并调用waiter的accept( )方法。

  9. Waiter接受了消息,并确认成功接收到所有的响应消息。唤醒Sender。

  10. Sender返回消息给client。

public class Sender {
    public IObject send(IObject request, long timeout) {
        String requestNo = getRequestNo();
        waiter = new Waiter(client, requestNo);
        client.waiters.put(requestNo, waiter);
        request.set("requestNo", requestNo);
        connection.send(request);
        waiter.standby(timeout);  // Block
        int state = waiter.getState(); // 0=waiting first, 1=waiting next, 2=timeout, 3=complete
        if (state == 3) {
            return waiter.getResult();
        } else {
            // create new response for failure.
        }
    }
}

public class Receiver {
    public void receive(IObject msg) {
        String requestNo = node.get("requestNo");
        Waiter waiter = client.waiters.get(requestNo);
        if (waiter != null) {
            if (waiter.accept(msg)) return;
        }
        // 如果消息不被接受,则发给MessageHandler来处理。        
        if (client.handler != null) {
            client.handler.handleMessage(msg);
        }
    }
}

public class Waiter {
    // 0=waiting first; 1=waiting second; 2=timeout; 3=complete 
    private int state=0;
    private List<IObject> messages;
    
    public synchronized void standby(long timeout) {
        try {
            this.wait(timeout);
        } catch (InterruptedException e) {
        }
        if (state < 2) {
            state = 2;
            client.waiters.remove(requestNo);
        }
    }
 
    public synchronized boolean accept(IObject msg) {
        if (state >= 2) {
            // waiter is closed
            return false;
        } 
         
        try {
            if (state == 0) {
                // 收到第一个返回的消息
                messages.add(msg)
                // 查看是否还有后续消息
                // 设置state的状态
                // 如果需要后续消息, return true
            }
            if (state == 1) {
                // 如果不是期待的消息类型, return false
                // 收到了后续消息
                messages.add(msg)
                // 设置状态
                // 如果需要后续消息, return true
            }
            state = 3;
            client.waiters.remove(requestNo);
            // 唤醒SDK
            this.notifyAll();
            return true;
        } catch (Exception e) {
            // 发生解析错误, 创建错误消息
            messages.add(err)
            state = 3;
            client.waiters.remove(requestNo);
            this.notifyAll();
            return true;
        } 
    }
    
    public synchronized IObject getResult() {
        // 将message列表中的消息合并成一个result
        return result;
    }
}


© 著作权归作者所有

共有 人打赏支持
xpbug
粉丝 300
博文 102
码字总数 125336
作品 0
浦东
程序员
关于Alipay支付宝接口(Java版)下

4.alipay 页面跳转同步通知处理 4.1 页面跳转同步通知   当买家完成了支付流程后,会出现成功支付的页面,该页面做短暂停留后,会跳转到我们AlipayConfig.xml中的 return_url 属性所指定的...

站在云端er
2016/08/22
20
0
ajax 同步和异步的区别|已迁移

同步会阻塞后面的代码,也就是说假设这个ajax请求要3 5秒,浏览器就会阻塞住3 5秒不执行后面的,知道等到ajax请求完成。 而且同步不能直接使用jsonp。 异步不能在回调之外直接拿到返回的dat...

辣条拌鱼翅
2015/07/20
0
0
将不确定变为确定~开发人员应该明确知道跨域Post的问题

注意:这里的跨域指不到同一域名下,包括一级与二级域名,这里也认为不在同域下 从A网站把信息以Post的方式发送到B网站,这种过程叫做跨域POST,相类的,A网站把B网站的信息获取回来,一般称...

mcy247
2017/12/05
0
0
爱上MVC3系列~当Ajax.Beform不能满足我们的要求时...

mvc架构中提供了Html.BeginForm与Ajax.BeginForm,主要实现同步提交表单与异步提交表单,对于同步提交与传统的方式没有区别,而异步表单MVC自己进行了封装(可以看我的文章了解两种方式的表单...

mcy247
2017/12/06
0
0
MongoDB学习笔记~为IMongoRepository接口添加了增删改方法,针对官方驱动

上一讲说了MongoDB官方驱动的查询功能,这回说一下官方驱动的增删改功能,驱动在升级为2.0后,相应的insert,update和delete都只有了异步版本(或者叫并行版本),这当然也是跟着.net走的正方...

mcy247
2017/12/06
0
0
ios的线程和同步异步操作

ios的线程和同步异步操作 ios的线程和同步异步操作 ios的多线程,同步异步操作,都是我们日常的开发中经常会遇到的问题,本文把常见的ios线程,同步异步的操作进行了整理。 代码下载: 我博客...

lewis-180
2015/12/08
57
0
支付宝同步异步的问题

小弟第一次做支付宝接口,有几个问题,想问开源大神么, 看了下API 支付流程是 先走异步,验证签名,订单一些信息, 如果异步返回success,然后在走同步做跳转页面, 流程是这样么?...

springss
2017/12/23
106
0
爱上MVC3系列~同步与异步提交,在过滤器里如何进行重定向~续

上一篇文章已经解决了同步与异步表单提交的页面重定向问题,而为什么要写个“续”呢,原因是,我觉得上次的代码不够美丽,而且有些啰嗦,也不符合我的代码之美原则,所以,我自己的代码进行了...

mcy247
2017/12/06
0
0
(转)Twisted :第一部分:初步认识Twisted

前言: 最近有人在Twisted邮件列表中提出诸如”为任务紧急的人提供一份Twisted介绍”的的需求。值得提前透露的是,这个序列并不会如他们所愿.尤其是介绍Twisted框架和基于Python 的异步编程而...

水果糖
2016/01/27
22
0
玩转iOS开发:实战开发中的GCD Tips小技巧 (一)

文章分享至我的个人技术博客: cainrun.github.io/15061581251… 这篇文章主要是给之前的文章作为一个补充, 顺便讲讲一些在实际开发中遇到的问题和一些解决的办法, 如果没有看过之前文章的朋友...

CainLuo
2017/11/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

istio源码分析之pilot-discovery模块分析

本文分析的istio代码版本为0.8.0,commit为0cd8d67,commit时间为2018年6月18日。 本文为Service Mesh深度学习系列之一: Service Mesh深度学习系列part1—istio源码分析之pilot-agent模块分...

xiaomin0322
5分钟前
0
0
数据库基本操作:增删改查及联表操作

所用软件:SQL Server Management Studio 首先第一步,建立一个表。在这里命名为T1。并在里面填入几条数据。如图: T1 一.查询 查询所有:select * from T1; 按条件查询:select * from T1 ...

小_橙_子
9分钟前
0
0
Crontab作业时间设置

今天,遇到这么一个题目,周一到周五的9:00-16:59之间,每隔两分钟将某个命令运行一次。给的答案是: */2 9-16 * * 1-5 /usr/sbin/somecommand dosomething 乍一看,这个答案不对,应...

大别阿郎
14分钟前
0
0
ES17-JAVA API文档管理

1.保存文档 可以通过json工具把java对象转换成json字符串进行保存,也可以通过内置的帮助类直接构建json格式 /** * 获取客户端 * * @return */public static TransportClie...

贾峰uk
15分钟前
0
0
Python代码规范和命名规范

前言 Python 学习之旅,先来看看 Python 的代码规范,让自己先有个意识,而且在往后的学习中慢慢养成习惯 一、简明概述 1、编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头...

blackfoxya
17分钟前
0
0
联动滑动之一:NestScrollChild和NestedScrollingParent

NestScrollChild和NestedScrollingParent 吐槽一下开源中国竟然标题字数有限制 由于项目中使用了CoordinateLayout来解决联动以及实现炫酷的UI效果,那么必须就要研究一波源码了,毕竟知其然知...

JerryLin123
35分钟前
1
0
cloudera spark2.2 读写hbase

cloudera spark2.2 读写hbase 例子 host = 'bigdata-03,bigdata-05,bigdata-04'conf = { "hbase.zookeeper.quorum": host, "hbase.mapreduce.inputtable": "student1"}k......

osenlin
39分钟前
0
0
数据库规范化

转载自 一个小时学会MySQL数据库 地址:http://www.cnblogs.com/best/p/6517755.html 截取其中 1.4 部分 用于自己学习使用 感谢作者:张果 1.4、数据库规范化 经过一系列的步骤,我们现在终于...

十万猛虎下画山
40分钟前
0
0
ios逆向之工具篇

Reveal:查看任意app的UI结构 注:1.不越狱的手机,可以用Reveal来查看自己app的UI结构,不能查看其它app的结构。 2.越狱手机上可以查看任意app的UI结构。 IDA:反编译工具 从App Store下载的...

HeroHY
40分钟前
0
0
EOS区块链平台智能合约示例HelloWorld

我们将介绍一个使用EOS智能合约构建hello World的例子。 一般环境设置通过上一篇文章已经说明,这方面的问题大家可以看本博客上一篇文章,本文引用了官方EOS在Git上的示例。 运行nodeos 要通...

笔阁
43分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部