1、处理异步结果

在内部,play框架是自下而上异步的。Play以异步、非阻塞方式处理每个请求。应用程序代码应尽量避免阻塞控制器,这种阻塞操作的常见例子有JDBC调用、流式API、HTTP请求和长计算。因此应尽量通过保持控制器异步的方法使得应用进行扩展,使系统在负载下保持响应。就是说,对于控制器中的一些阻塞的操作,尽量使用异步的方式进行处理。

Action中的处理要求尽可能的快,但是如果使用异步(Action默认处理请求就是异步的),那么可能会有这样的问题,结果没有计算出来,响应就已经返回了,这是怎么处理呢?Java 8中提供了类CompletionStage和CompletableFuture这两个类不具体介绍,只需要知道可以实现使得程序异步又可以获取返回值,CompletionStage<result>最终将用result类型的值。返回CompletionStage<result>是一种编写非阻塞代码的技术。可以使用如下方式获取:

实现异步处理、非阻塞编程的关键就在于CompletionStage,下边介绍一下如何使用,第一种可以通过配合HttpExecutionContext使用,可以通过依赖项注入play提供的play.libs.concurrent.httpExecutionContext实例,如下:

只是使用HttpExecutionContext和CompletableFuture还是使用的play默认的上下文执行器,还需要使用CustomExecutionContext和HttpExecution实现非阻塞编程,如下:

可以通过使用实现响应超时问题的处理:

2、流式HTTP响应

为了保持单个连接的开放性以服务于多个HTTP请求和响应,服务器必须随响应一起发送适当的内容长度的HTTP头。对于响应一些简单的文本结果,play可以自动识别并自动添加头信息返回客户端,但是对于一些复杂的内容,就需要开发者自己指定头信息,play提供了类play.http.httpentity用来实现此功能,使用如下:

在这里就有一个问题,为了计算头长度获取头信息,就需要将所有返回内容加载到内存,这里就可能存在问题:返回内容太大怎么办?下边先来一个返回结果的例子:

这里返回到客户端一个流对象,由于需要判断头信息,而play不能在流中直接获取头信息,这是就需要将整个流添加到内存中进行分析。Play中对于此问题,早已提供实现,直接调用ok(new File(“文件路径”))即可。

上边这种方式返回的文件大小必须是确定的,对于文件大小不能确定的、动态变化的就需要使用分块传输编码技术,使用如下:

3、Comet套接字

使用分块传输编码技术实现Comet。Comet套接字是一个分块的text/HTML响应,只包含<script>元素。对于每个块,我们编写一个包含JavaScript的<script>标记,该标记立即由Web浏览器执行。这样我们就可以从服务器向Web浏览器实时发送事件:对于每条消息,将其包装成一个调用javascript回调函数的<script>标记,并将其写入分块响应。

因为ok().chunked利用akka流获取流<bytestring>,所以我们可以发送一个元素流并对其进行转换,以便在javascript方法中对每个元素进行转义和包装。Comet帮助程序自动执行Comet套接字,为浏览器兼容性推送初始空白缓冲区数据,并支持字符串和JSON消息。

下边介绍几个Comet的使用:

字符串流中使用Comet:

Json流中使用Comet:

Iframe中使用Comet:

4、WebSockets(网络套接字)

WebSockets是基于允许双向全双工通信的协议从Web浏览器使用的套接字。只要服务器和客户机之间有活动的WebSocket连接,客户机就可以发送消息,服务器就可以随时接收消息。WebSokets不能通过标准动作来处理。Play的WebSocket处理机制是围绕Akka流构建的。WebSocket被建模为流,传入的WebSocket消息被送入流中,流生成的消息被发送到客户机。play提供了一些在WebSocket中构造WebSocket的工厂方法。

接下来介绍play中如何处理websocket。

使用actors处理websocket,可以使用play实用程序ActorFlow将actorRef转换为流。此实用程序接受一个函数,该函数将actorRef转换为向akka.actor.props对象发送消息,该对象描述在接收WebSocket连接时play应创建的参与者:

从客户端接收到的任何消息都将发送给参与者,而由play提供的任何消息都将发送给客户端,当websocket关闭时,actor将被停止,可以通过实现actors的 poststop方法来处理需要关闭的资源:

有时候希望拒绝WebSocket请求,例如,如果必须对用户进行身份验证才能连接到WebSocket,Play为此目的提供了AcceptorResult  WebSocket  Builder:

想要实现异步接收WebSocket,直接使用CompletionStage<WebSocket<A>>代替WebSocket<A>即可。

处理其他类型数据的请求:

还可以直接使用akka流处理WebSockets,如下:

WebSocket可以访问请求头(来自启动WebSocket连接的HTTP请求),但是,它不能访问请求主体,也不能访问HTTP响应

发送hello之后丢弃输入数据并关闭套接字:

输入数据记录到标准输出,然后使用映射流发送回客户机:

配置websocket的帧长度有两种方式,在启动应用是使用:

play.server.websocket.frame.maxLength 或者

Sbt -Dwebsocket.frame.maxLength=256k run

2、异步HTTP编程相关推荐

  1. angular之Rxjs异步数据流编程入门

    Rxjs介绍 参考手册:https://www.npmjs.com/package/rxjs 中文手册:https://cn.rx.js.org/ RxJS 是 ReactiveX 编程理念的 Jav ...

  2. io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程

    图/文:迷神 我们在Python爬虫中,重要的是讲究速度,如果有10万或者100万Url地址,写过爬虫的都会知道,那估计是非常慢的.我们的Python爬虫一般IO密集型业务,Python爬虫程序需要发 ...

  3. python 异步io_python异步IO编程(一)

    python异步IO编程(一) 基础概念 异步IO (async IO):一种由多种语言实现的与语言无关的范例(或模型). asyncio:Python 3.4版本引入的标准库,直接内置了对异步IO的 ...

  4. python 异步io 写excel_python异步IO编程(二)

    python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 importasync ...

  5. Python 异步网络编程实战

    Python 异步网络编程实战 - songcser - 掘金小册 小册介绍 第一部分是对 Python 协程的讲解,从字节码开始简单讲解了 Python 虚拟机的执行过程,可以大体了解到 Pytho ...

  6. Springboot异步多线程编程

    文章目录 一.基础知识 二.什么时候用同步&异步 三.什么时候需要使用多线程 四.springboot异步多线程编程实现 一.基础知识 同步:同步就是指一个进程在执行某个请求的时候,若该请求需 ...

  7. linux的socket模型有哪些,异步io 编程 Linux Socket五种I/O模型(zhuan(3)

    需要说明的是并非所有的Windows SocketsAPI在非阻塞模式下调用,都会返回WSAEWOULDBLOCK错误.例如,以非阻塞模式的套接字为参数调用bind()函数时,就不会返回该错误代码.当 ...

  8. Spring / Spring boot 异步任务编程 WebAsyncTask

    今天一起学习下如何在Spring中进行异步编程.我们都知道,web服务器处理请求request的线程是从线程池中获取的,这也不难解释,因为当web请求并发数非常大时,如何一个请求进来就创建一条处理线程 ...

  9. 5.4 异步TCP编程(一)

    2019独角兽企业重金招聘Python工程师标准>>> 摘自<C#网络应用编程>(第2版) 看到网上资料很少,做个摘录,如有版权问题,请告知. 利用TcpListener ...

最新文章

  1. python py生成及调用pyd(so)文件
  2. 编程实现启用禁用网卡
  3. 如何在Timeline中使用Cinemachine?
  4. left join条件放在on和where的区别
  5. Ubuntu 16.04 安装 CUDA10.1 (解决循环登陆的问题)
  6. .ashx接口单元测试
  7. 「收藏」其实是欺骗自己
  8. 1007. 素数对猜想 (20)
  9. 处理 TXT 文本技巧
  10. 快速拓展领英人脉网9大秘诀,让我们更高效的使用领英
  11. 互联网平台掘金三四五线城市,你需要知道的9.9个真相
  12. Oracle查询上周日期sql,Oracle 获取上周一到周末日期的查询sql语句
  13. (原创)ics-openvpn编译详解
  14. 【C++】继承详解,菱形继承问题
  15. PLC控制模拟量输入\输出方式
  16. 全志v3s学习笔记(8)——TF卡分区及烧录
  17. mysql综合案例 数据表的基本操作
  18. 八门神器java_【修改教程】Java 运算符的说明_八门神器
  19. Javascript判断是否iphone全面屏手机
  20. 使用c++实现学生成绩管理系统

热门文章

  1. oracle导入视图报错,exp/imp 报错处理(EXP-00003 / IMP-00019 / IMP-00058)
  2. mysql 8 配置参数优化_mysql8 参考手册--配置非持久性优化器统计参数
  3. linux 用mutex定义一个linkedlist,一个高性能无锁非阻塞链表队列
  4. 后端学习 - RabbitMQ
  5. 「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
  6. By Elevator or Stairs? CodeForces - 1249E(动态规划)
  7. Newton Method in Maching Learning
  8. P2770 航空路线问题(网络流)
  9. XXI Open Cup. Grand Prix of Korea I. Query On A Tree 17 树剖 + 二分 + 树带权重心
  10. Loj #6274. 数字 数位dp + 去重