Elixir的Phoenix框架:请求处理之道
本文基于Phoenix1.3,但请求的处理流程跟1.2基本一致,只是模块的命名和目录结构有所差异。
简单介绍,phoenix是一个网站框架,本质就是http请求处理。这篇文章主要就是讲一个请求,在结果回到用户之前,走过了哪些路。通过这种方式,介绍phoenix框架中各个组成部分(包括endpoint、routing、controller、view、template、channel)。仅作phoenix框架入门之用,未涉及底层cowboy框架。
上图(我很丑也并不温柔,手残作者 ==! ):

以上是基本上所有的请求走的路,绿色部分表示正儿八经的请求,其他的杂色则表示连接、加入频道等前期准备工作。
请求主要分三类:静态资源、动态资源或http请求、websocket请求。其中前两类均为一次性连接,每次请求均启动一个新进程进行处理,回复完成后会话结束。而websocket方式则是长期存在的连接,可进行双向通信。
一、请求静态资源
静态资源即不用经过任何处理,可以直接返回给用户的资源。如图,静态资源进入endpoint即返回。在endpoint.ex中有下面这段,这一段就定义了可以直接返回给用户的静态资源,资源放在priv/static/目录下。这类资源直接以文件形式返回给用户,不经过后续处理流程。
plug Plug.Static,
at: "/", from: :my_app, gzip: false,
only: ~w(css fonts images js index.html)
二、动态资源或http请求
这部分指的是非web_socket的请求,通常是需要进行一定的处理和渲染才能返回给客户端的资源或数据。在图中的下半部分有所展示,主要涵盖router、controller、view、template部分。
1.消息首先经过endpoint进行一些初始化处理,如解码等,endpoint就是一个流水线,流水线的最后一步走入router中进行路由。
2.在router中也可以定义不同的流水线,根据请求路径和请求方式,对请求方进行权限验证或其他自定义的数据初始化。所有验证通过后,会根据定义的路由,分发进入不同的controller中进行最终处理。
3.controller是实际处理请求的地方,服务端请求处理逻辑所在处。在controller中处理完成后,可以调用不同的接口,直接回复给用户(如: text(conn, "ok") ),或者调用渲染方法(如:render(conn, "homePage.html", param: param) ),并传入返回参数。
4.渲染主要在与controller的前缀相同的view中进行,如果是文件模板,则会从 templates/xyz 目录下找对应的模板,然后用传入参数进行渲染。渲染完后发送给用户。
三、websocket请求
这部分是图中的上半部分,主要涵盖socket、channel部分。Phoenix框架的websocket中有一个channel的概念,可围绕channel做消息转发、广播等,甚至也可以做api请求。
1. 连接socket
加入socket的url,在endpoint.ex中有定义,如下:
socket "/socket", AppWeb.XyzSocket
即,通过websocket连接 www.example.com/socket 可对应到AppWeb.XyzSocket模块进行连接处理。处理连接的是新生的一个进程,该进程调用AppWeb.XyzSocket模块的 connect/2 函数进行初始化,该函数返回:error则表示连接失败,{:ok, socket}则表示连接成功。失败的话进程退出,成功则进程保留,用以用户消息的收发。此过程为图中红色线所示。
2.加入channel
在连接socket的时候,AppWeb.XyzSocket模块中会定义可连接的channel及对应处理模块,如下:
channel "abc:*", AppWeb.AbcChannel
当用户加入"abc:"开头的channel时,会启动一个channel进程,调用 AppWeb.AbcChannel.join/2 函数进行处理,该函数中可做一些权限验证和频道的初始化。如果该函数返回{:ok, socket}则表示加入成功,进程保留为该用户在此频道中的数据交流之用。返回{:error, reason}则加入失败,进程退出。此过程为图中蓝色线所示。
3.channel消息
用户加入channel后,可往channel发送消息(如图中上半部分绿线流程),channel也可以主动往客户端推送消息(如图中橙色线所示)。如图所示,其消息收发都是要经过socket进程,不过socket进程的转发属于隐形的过程,写代码时涉及不多。
用户向channel发送消息时,会在对应的channel进程调用 AppWeb.AbcChannel.handle_in/2 函数进行消息处理。处理完后函数返回 {:reply, reply, socket} 即可把reply返回给用户(底层经由socket进程)。
channel通过调用 push 或 broadcast 接口(详见官方文档)可以主动向用户发送消息。
结束语
所谓的XX之道多半是讲“道”,而我的“道”是道路的“道”。哈哈哈,总感觉一不小心起了个大名字。
Elixir的Phoenix框架:请求处理之道的更多相关文章
- JavaSSM框架精选50道面试题
JavaSSM框架精选50道面试题 2019年02月13日 19:04:43 EerhtSedah 阅读数 7760更多 分类专栏: 面试题 版权声明:本文为博主原创文章,遵循CC 4.0 BY- ...
- MVC框架请求处理
为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平.你的一个决定会影响团队未来的几年.要考虑方面太多: 简单易用,以提高开发效率.使小部分的精力在框架上,大部分的 ...
- PE框架学习之道:PE框架——发送报文流程
PE框架发送报文,适用于PE及VX技术 步骤: 1.在action中使用发送报文,要指定报文在router端的交易名称 2.如果使用supe.execute(context)来发送,不需要第一步 3. ...
- 框架学习之道:PE框架简介
1.PE框架开发新功能所需的部分 2.PE框架工作流程(重要) 首先根据<transcation>中的id号,找到模板(template),然后再根据模板找到责任链(chain),一旦确认 ...
- PE框架学习之道:PE框架——style的配置
1.在style.xml中定义style <style id="NumberStyle"> <setting> <param name=&qu ...
- phoenix API服务发布
概述 Elixir 的 Phoenix 框架对于开发 Web 应用非常方便,不仅有 RoR 的便利,还有 Erlang 的性能和高并发优势. 但是应用的发布涉及到 Erlang 和 Elixir 环境 ...
- phoenix 使用activerecord模式框架ecto 访问数据库
备注: 需要先安装mysql 以及phoenix 框架,测试使用的是docker 进行安装,具可以参考代码 1. 创建项目 mix phx.new first --database mys ...
- elixir学习
安装 brew install elixir atom配置 language-elixir atom-elixir elixir的shell iex :erlang.system_info(:otp_ ...
- phoenix初步
更新系统包管理工具hex mix local.hex 安装phoenix,phoenix是elixir的web框架 mix archive.install https://github.com/pho ...
随机推荐
- Javaweb 项目内所有页面都是404问题
这两天出现的问题:项目内所有的页面都是404 问题原因:Tomcat在启动时出现了问题导致服务器根本没启动起来 问题的根本原因: 由于之前用到了拦截器,然后拦截器没用了被我删掉了,但是web.xml文 ...
- AI 系列 总目录
AI 系列 答应了园区大牛 张善友 要写AI 的系列博客,所以开始了AI 系列之旅. 一.四大平台系列(百度AI.阿里ET.腾讯.讯飞) 1.百度篇 (1) 百度OCR文字识别-身份证识别 (2) 基 ...
- bzoj 4566: [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- 1.QT开发第一个程序
Ubuntu16.04安装QT5.8.0:http://www.cnblogs.com/dotnetcrazy/p/6725945.html QT5.8支持中文输入法(附带老版本的解决+不理想的情况解 ...
- 使用JavaScript将图片保存至本地
在最近的开发当中,我们需要为img标签以及canvas动态绘制的图像提供下载功能,下面是经过探索后我们得出的结果. 一.Canvas 版本 // 下载Canvas元素的图片 function down ...
- Oracle12c_安装1——准备工作
1.建议用户和组 su root #切换到root groupadd oinstall #创建用户组oinstall groupadd dba #创建用户组dba useradd -g oinstal ...
- Java订单号生成,唯一订单号(日均千万级别不重复)
Java订单号生成,唯一订单号 相信大家都可以搜索到很多的订单的生成方式,不懂的直接百度.. 1.订单号需要具备以下几个特点. 1.1 全站唯一性. 1.2 最好可读性. 1.3 随机性,不能重复,同 ...
- PHP call_user_func
<?php function my_call_back_function(){ echo "hello world!"; } class MyClass{ static fu ...
- getComputedStyle与currentStyle获取样式(style/class)
今天看jQuery源码CSS部分,里面用到了currentStyle和getComputedStyle来获取外部样式. 因为elem.style.width只能获取elem的style属性里的样式,无 ...
- 使用XML序列化实现系统配置 - 开源研究系列文章
在实际的C#软件系统开发过程中,会遇到系统配置的保存问题,以及系统存储问题.在以前的系统开发过程中,笔者使用的是INI文件配置管理的方式.到了现在,INI文件配置保存仍然是一个平常使用的方式.在博客园 ...