Phoenix.Channel.push

第一次接触 phoenix 框架时, 照着官网的教程做了一个聊天网页. 服务器可以在 channel 里广播消息, 还可以 push 消息给单个用户. phoenix 究竟是如何做到的. 我们先看看该函数的定义

  @doc """Sends event to the socket.The event's message must be a serializable map.## Examplesiex> push socket, "new_message", %{id: 1, content: "hello"}:ok"""def push(socket, event, message) do%{transport_pid: transport_pid, topic: topic} = assert_joined!(socket)Server.push(transport_pid, topic, event, message, socket.serializer)end

首先, 调用了 assert_joined!/1 函数, 来看看它有什么用

  defp assert_joined!(%Socket{joined: true} = socket) dosocketenddefp assert_joined!(%Socket{joined: false}) doraise """`push`, `reply`, and `broadcast` can only be called after the socket has finished joining.To push a message on join, send to self and handle in handle_info/2, ie:def join(topic, auth_msg, socket) do...send(self, :after_join){:ok, socket}enddef handle_info(:after_join, socket) dopush socket, "feed", %{list: feed_items(socket)}{:noreply, socket}end"""end

原来只是确认一下该 socket 是否已加入频道, 会返回一个很详细的错误提示, 教你如何在 join 时 push 消息, 也许是因为很多人提了这个问题吧.

从 socket 中获取到 transport_pid, topicserializer 之后, 调用了 Server.push 函数.

Phoenix.Channel.Server.push

  @doc """Pushes a message with the given topic, event and payloadto the given process."""def push(pid, topic, event, payload, serializer)when is_binary(topic) and is_binary(event) and is_map(payload) doencoded_msg = serializer.encode!(%Message{topic: topic,event: event,payload: payload})send pid, encoded_msg:okenddef push(_, _, _, _, _), do: raise_invalid_message()

Server.push 函数将收到的 topic , eventpayload 编码之后, 发送给了 transport. 那么 transport 会对这些信息作何处理呢?

cowboy_websocket:handler_loop

我们先暂停一下, 说说客户端加入某个 channel 时究竟发生了什么. 当客户端与服务器的连接建立后, 会生成一个 transport 进程, 随后客户端加入某个 channel 时, transport 进程又会生成一个 channel 进程. 当客户端断开连接后, transport 进程会死亡, 其下的 channel 进程也会随之死去. 所以每个用户加入的每个 channel 都有一个独立的进程, 用于保存一个 %Phoenix.Socket{} 结构体.

让我们继续之前的线索, 通过 observer, 我们找到了 tansport 进程中正在运行的函数 -- cowboy_websocket:handler_loop. 此后便是 cowboy 将消息通过 websocket 发送给客户端了.

总结

phoenix channel 中的消息 push 机制很简单, 与关注同一个 channel 的其他人没有关系. 进程关系如图

下回我们将看看 phoenix 是如何广播消息的.

[elixir! #0024] 引擎盖下, `Channel.push` 如何运作相关推荐

  1. [elixir! #0023] 引擎盖下, `IO.puts` 如何运作

    `IO.puts "Hello world!" 接触elixir时, 学会的第一行代码是 IO.puts "Hello world!". 出于好奇, 我观察了一 ...

  2. 规则引擎 设计 git_引擎盖下的Git

    规则引擎 设计 git by Wassim Chegham 由Wassim Chegham 引擎盖下的Git (Git under the hood) Let's explore some commo ...

  3. 详解PPP模式下的产业投资基金运作【基金管理】

    详解PPP模式下的产业投资基金运作[基金管理] 点击标题下「搏实资本」可快速关注 搏实资本 研究型的投资机构,实操型的专家团队 ﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌ 一.产业投资基金概述 1.产业投资基 ...

  4. 供应链环境下,制造企业物流运作模式该如何选择

    随着经济全球化的快速发展,市场竞争已由单个企业之间的竞争逐渐转变为供应链之间的竞争,企业要想获得竞争优势,必须实施供应链战略资源整合.作为一种新的管理思想和管理方法,供应链管理是通过管控(计划.组织. ...

  5. Windows下Git push or pull免输入密码设置

    2019独角兽企业重金招聘Python工程师标准>>> ####Windows 针对Win下采用msysgit作为Git客户端的环境 在Windows中添加一个HOME环境变量,值为 ...

  6. 对话英特尔副总裁Erez Dagan:自动驾驶引擎盖下的秘密!|《新程序员》

    以芯片.摄像头.软件为基石,依托人工智能.大数据等前沿技术,从数据处理.传输.分析到数据安全,纵横于数十年创新经验之上,看半导体巨头英特尔如何布局自动驾驶. 作者 | 屠敏 徐威龙 出品 | < ...

  7. iOS自定义push动画-从下向上push

    - (void)push { CATransition *transition = [CATransition animation]; transition.duration = 0.4f; tran ...

  8. ubuntu系统下git push时出现问题 git clone:Failed to connect to github.com port 443: Connection refused解决办法

    在VMware虚拟机Ubuntu20.04上git push ORB_SLAM2 项目时出现了如下报错 解决方案: 如果没有开vpn 首先将 http://github.com/任意项目路径 切换为 ...

  9. 快收下这份“数据库运作实践”秘制口诀

    小时候,我们用九九口诀帮助学习乘法,如今,我们用朗朗上口的口诀,帮助DBA熟记工作纲领.这份口诀,来自于一位深耕数据库领域15年的资深DBA--21CN 成思敏,日复一日的实践中总结出的精华,分享至此 ...

  10. isam_引擎盖下的ISAM ESSO

    isam 存档日期:2019年5月13日 | 首次发布:2013年2月26日 本文深入研究了用于企业单一登录(ISAM ESSO)的IBM Security Access Manager配置故障排除. ...

最新文章

  1. windows linux rac,跨平台表空间传输(windows到linux RAC)
  2. Redis 宝典 | 基础、高级特性与性能调优
  3. centos图形界面和文本界面登陆切换设置
  4. c语言字母输出什么意思,C语言中字符的输入输出以及计算字符个数的方法详解...
  5. what is conversion exit defined in ABAP domain
  6. Maven基础了解及配置信息
  7. js打开android应用程序,浏览器通过JS打开Android程序
  8. VBScript:登录脚本
  9. 敏捷开发团队管理系列之二:程序与测试团队I
  10. JSK-118 输出格式练习【入门】
  11. python程序设计和c语言_C 语言和 Python,该从哪个入门编程?
  12. JavaScript实现map
  13. 【文献翻译】基于CVSS的IT系统网络安全风险定量评估方法-A Quantitative CVSS-Based Cyber Security Risk Assessment Methodology
  14. 【JDK】Mac版安装JDK并配置环境
  15. 实例总结C#反射基础知识[原创]
  16. 如何用python把pdf转为word_如何使用python将双栏pdf转换成word?
  17. python3__机器学习__神经网络基础算法__偏执项b
  18. 去掉input自动填充的黄色背景
  19. c语言怎么让电脑backspace,backspace键在哪里
  20. WPF 基于 WER 注册应用崩溃无响应回调和重启方法

热门文章

  1. 32点亮8个呼吸灯_艾扬格瑜伽32 个经典体式 amp; 2 大呼吸法经典示范图(收藏级)...
  2. redis依赖包_解决痛点:二方包稳定性测试实践
  3. 基于 display 和 javaScript 封装一个页面布局小插件
  4. Python Window10 环境安装流程
  5. uni-app在h5端和app端的使用。/deep/ css兼容性问题如何解决?
  6. Xcode设置编译链接-framework CoreFoundation
  7. java3d/j3d源码位置
  8. 搭建Eclipse 2020安卓开发环境
  9. WINDOWS下获得DLL所在目录的代码
  10. LINUX下载编译FreeType