接上 ranch 源码分析(三)

在上一次,根据ranch源码把大概流程理了一遍,下面我们将一些细节解释一下。

ranch只是一个服务的框架,它提供了传输层协议代码(ranch_tcp 和ranch_ssl),

大概可以看看这2个的源码,其实就是gen_tcp和gen_ssl的封装。

它做的工作可以分成

  1、根据port配置开启一个端口的linsten,(具体见ranch_acceptors_sup.erl代码)

  2、然后开启N个(根据设置)进程accpet等待client的连接, (具体见ranch_acceptors_sup.erl和ranch_acceptor.erl源码)

  3、当client连接,启动一个用户定义的应用protocol ,记录pid,(具体见ranch_conns_sup.erl源码)

  4、并把步骤2连接的socket的管理者改为步骤3的pid,剩下的就是应用模块去处理client的请求了,没ranch什么事情了(具体见下)

首先在ranch_acceptor.erl中有如下代码

-module(ranch_acceptor).

-export([start_link/3]).
-export([loop/3]).

%.......省略若干行
-spec loop(inet:socket(), module(), pid()) -> no_return().
loop(LSocket, Transport, ConnsSup) ->
_ = case Transport:accept(LSocket, infinity) of
{ok, CSocket} ->
case Transport:controlling_process(CSocket, ConnsSup) of
ok ->
%% This call will not return until process has been started
%% AND we are below the maximum number of connections.
ranch_conns_sup:start_protocol(ConnsSup, CSocket);
{error, _} ->
Transport:close(CSocket)
end;
%% Reduce the accept rate if we run out of file descriptors.
%% We can't accept anymore anyway, so we might as well wait
%% a little for the situation to resolve itself.
{error, emfile} ->
receive after 100 -> ok end;
%% We want to crash if the listening socket got closed.
{error, Reason} when Reason =/= closed ->
ok
end,
%.......省略若干行

标记的地方能看到首先client连接成功的时候,会把scoket的所有者设置为Connsup 的pid

然后在ranch_conns_sup.erl里面

-module(ranch_conns_sup).

%% API.
-export([start_link/6]).
-export([start_protocol/2]).
-export([active_connections/1]).

%.......省略若干行

shoot(State=#state{ref=Ref, transport=Transport, ack_timeout=AckTimeout, max_conns=MaxConns},
CurConns, NbChildren, Sleepers, To, Socket, SupPid, ProtocolPid) ->
case Transport:controlling_process(Socket, ProtocolPid) of
ok ->
ProtocolPid ! {shoot, Ref, Transport, Socket, AckTimeout},
put(SupPid, true),
CurConns2 = CurConns + 1,
if CurConns2 < MaxConns ->
To ! self(),
loop(State, CurConns2, NbChildren + 1, Sleepers);
true ->
loop(State, CurConns2, NbChildren + 1, [To|Sleepers])
end;
{error, _} ->
Transport:close(Socket),
%% Only kill the supervised pid, because the connection's pid,
%% when different, is supposed to be sitting under it and linked.
exit(SupPid, kill),
loop(State, CurConns, NbChildren, Sleepers)
end.
%.......省略若干行

如上在Connsup中,会把scoket的所有者设置成Protocol启动处理业务的Pid~~~

然后就没有然后呢,其实ranch只是一个框架,具体的应用实现还是要靠用户去编写,

不过好在我们有优秀的例子,比如cowboy的新版(V1.0.4版本以上)就是ranch的最好的例子之一。

ranch的介绍到这里就结束了,读者有疑问的请到下面提出。

ranch 源码分析(完)的更多相关文章

  1. ranch 源码分析(二)

    接上ranch 源码分析(一) 上次讲到了ranch.erl的start_listener函数,下面我们详细分析下这个函数 -module(ranch). %...... 省略若干行 -spec st ...

  2. ranch 源码分析(三)

    接上ranch 源码分析(二) 上次讲到了ranch_conns_sup和ranch_acceptors_sup这2个ranch的核心模块,我们接着分析 首先查看ranch_conns_sup.erl ...

  3. ranch 源码分析(一)

    以前写了一个ranch的处理流程,http://www.cnblogs.com/tudou008/p/5197314.html ,就只有一张图,不是很清晰,现在有空做个源码分析. ranch的源码(版 ...

  4. cowboy源码分析(一)

    前段时间导读了ranch的源码,具体见ranch 源码分析(一), 现在整理了下ranch框架下经典应用cowboy. 源码地方:https://github.com/ninenines/cowboy ...

  5. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  6. HashMap源码分析(二):看完彻底了解HashMap

    上文讲到HashMap的增加方法,现在继续 上文链接 HashMap在上一篇源码分析的文章中,如果使用put的时候如果元素数量超过threshold就会调用resize进行扩容 1.扩容机制 想要了解 ...

  7. cowboy源码分析(二)

    接 cowboy源码分析(一) 下面我们重点看看cowboy_protocol.erl代码 -module(cowboy_protocol). %% API. -export([start_link/ ...

  8. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  9. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

随机推荐

  1. C# 实现http不同方法的请求

    p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...

  2. arcgis for js symbol图标的变化

    需求是图标有hover效果 ,如下 思路 : 1.创建图片标记,并赋值: args.rendererArgs = new RenderArgs();     args.rendererArgs.typ ...

  3. go语言入门教程:基本语法—常量constant

    一.常量的使用 1.1 常量声明 常量是一个简单值的标识符,在程序运行时,不会被修改的量. const identifier [type] = value 显式类型定义: const b string ...

  4. 通过Charles获取看书神器API

    Charles Charles是一个可以做HTTP代理/ HTTP监视器/反向代理的软件,使开发人员能够查看其机器和Internet之间的所有HTTP和SSL / HTTPS流量.包括请求,响应和HT ...

  5. PHP 农历公历互转,八字排盘,星座,日历,支持从-1000到3000年间的排盘,二十四节气

    <?php /** * @author szargv@wo.cn * * 此日历转换类完全源于以下项目,感谢这两个项目作者的无私分享: * https://github.com/nozomi19 ...

  6. django分页功能实现

    django内置的分页功能需要引入内置模块from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger Pagina ...

  7. bzoj4710 [Jsoi2011]分特产(容斥)

    4710: [Jsoi2011]分特产 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 814  Solved: 527[Submit][Status] ...

  8. httplib和urllib2常用方法

    都是几年前用过的,现在翻出来记录一下. import httplib import urllib2 import socket ##---------------------------------- ...

  9. linux常用英文单词记录

    1.skip 跳过忽略 2.next 下一步3.hostname 主机名4.password 密码5.complete 完成6.network 网络7.conf config configuratio ...

  10. ORACLE 12c RAC的常用管理命令

    ORACLE 12c RAC的常用管理命令 一.查询 1.RAC查询 1.1.查询节点 [grid@swnode1 ~]$ su - grid [grid@swnode1 ~]$ /u01/app/1 ...