2、异步HTTP编程
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编程相关推荐
- angular之Rxjs异步数据流编程入门
Rxjs介绍 参考手册:https://www.npmjs.com/package/rxjs 中文手册:https://cn.rx.js.org/ RxJS 是 ReactiveX 编程理念的 Jav ...
- io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程
图/文:迷神 我们在Python爬虫中,重要的是讲究速度,如果有10万或者100万Url地址,写过爬虫的都会知道,那估计是非常慢的.我们的Python爬虫一般IO密集型业务,Python爬虫程序需要发 ...
- python 异步io_python异步IO编程(一)
python异步IO编程(一) 基础概念 异步IO (async IO):一种由多种语言实现的与语言无关的范例(或模型). asyncio:Python 3.4版本引入的标准库,直接内置了对异步IO的 ...
- python 异步io 写excel_python异步IO编程(二)
python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 importasync ...
- Python 异步网络编程实战
Python 异步网络编程实战 - songcser - 掘金小册 小册介绍 第一部分是对 Python 协程的讲解,从字节码开始简单讲解了 Python 虚拟机的执行过程,可以大体了解到 Pytho ...
- Springboot异步多线程编程
文章目录 一.基础知识 二.什么时候用同步&异步 三.什么时候需要使用多线程 四.springboot异步多线程编程实现 一.基础知识 同步:同步就是指一个进程在执行某个请求的时候,若该请求需 ...
- linux的socket模型有哪些,异步io 编程 Linux Socket五种I/O模型(zhuan(3)
需要说明的是并非所有的Windows SocketsAPI在非阻塞模式下调用,都会返回WSAEWOULDBLOCK错误.例如,以非阻塞模式的套接字为参数调用bind()函数时,就不会返回该错误代码.当 ...
- Spring / Spring boot 异步任务编程 WebAsyncTask
今天一起学习下如何在Spring中进行异步编程.我们都知道,web服务器处理请求request的线程是从线程池中获取的,这也不难解释,因为当web请求并发数非常大时,如何一个请求进来就创建一条处理线程 ...
- 5.4 异步TCP编程(一)
2019独角兽企业重金招聘Python工程师标准>>> 摘自<C#网络应用编程>(第2版) 看到网上资料很少,做个摘录,如有版权问题,请告知. 利用TcpListener ...
最新文章
- python py生成及调用pyd(so)文件
- 编程实现启用禁用网卡
- 如何在Timeline中使用Cinemachine?
- left join条件放在on和where的区别
- Ubuntu 16.04 安装 CUDA10.1 (解决循环登陆的问题)
- .ashx接口单元测试
- 「收藏」其实是欺骗自己
- 1007. 素数对猜想 (20)
- 处理 TXT 文本技巧
- 快速拓展领英人脉网9大秘诀,让我们更高效的使用领英
- 互联网平台掘金三四五线城市,你需要知道的9.9个真相
- Oracle查询上周日期sql,Oracle 获取上周一到周末日期的查询sql语句
- (原创)ics-openvpn编译详解
- 【C++】继承详解,菱形继承问题
- PLC控制模拟量输入\输出方式
- 全志v3s学习笔记(8)——TF卡分区及烧录
- mysql综合案例 数据表的基本操作
- 八门神器java_【修改教程】Java 运算符的说明_八门神器
- Javascript判断是否iphone全面屏手机
- 使用c++实现学生成绩管理系统
热门文章
- oracle导入视图报错,exp/imp 报错处理(EXP-00003 / IMP-00019 / IMP-00058)
- mysql 8 配置参数优化_mysql8 参考手册--配置非持久性优化器统计参数
- linux 用mutex定义一个linkedlist,一个高性能无锁非阻塞链表队列
- 后端学习 - RabbitMQ
- 「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
- By Elevator or Stairs? CodeForces - 1249E(动态规划)
- Newton Method in Maching Learning
- P2770 航空路线问题(网络流)
- XXI Open Cup. Grand Prix of Korea I. Query On A Tree 17 树剖 + 二分 + 树带权重心
- Loj #6274. 数字 数位dp + 去重