Ejabberd源码解读-ejabberd_listener模块

本文深入解析ejabberd_listener模块,介绍了ejabberd如何启动端口监听,包括ejabberd_c2s、ejabberd_s2s_in和ejabberd_http服务。讲解了ejabberd_socket、ejabberd_receiver和ejabberd_c2s模块的功能,以及gen_server和gen_fsm在处理连接和XML信息中的作用。同时,提到了proc_lib模块在进程创建中的应用。
摘要由CSDN通过智能技术生成

ejabberd_listener模块启动分为两部分
1 启动端口监听
查看ejabberd_app.erl文件,启动过程语句

%%%启动一个supervisor,并启动和监控定义子进程
Sup = ejabberd_sup:start_link()

其中启动项包括ejabberd_listener:start_link/0

Listener =
    {ejabberd_listener,
     {ejabberd_listener, start_link, []},
     permanent,
     infinity,
     supervisor,
     [ejabberd_listener]},

以下为程序启动跟踪流程

start_link() ->
    supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
init(_) ->
    %%%新建listen_sockets表
    ets:new(listen_sockets, [named_table, public]),
    %%%端口绑定
    bind_tcp_ports(),
    {ok, {
  {one_for_one, 10, 1}, []}}.
bind_tcp_ports() ->
    %%%获取配置文件信息
    case ejabberd_config:get_option(listen, fun validate_cfg/1) of
    undefined ->
        ignore;
    Ls ->
        lists:foreach(
          fun({
  Port, Module, Opts}) ->
              ModuleRaw = strip_frontend(Module),
              case ModuleRaw:socket_type() of
              independent -> ok;
              _ ->
                  bind_tcp_port(Port, Module, Opts)
              end
          end, Ls)
    end.

注:查看ejabberd_config:get_option/2执行结果,由此可知,配置文件需监听3端口详细配置
(可调用执行ejabberd_config:get_option(listen,fun ejabberd_listener:validate_cfg/1).)

[{
   {5222,{0,0,0,0},tcp},
  ejabberd_c2s,
  [{
   access,c2s},{
   shaper,c2s_shaper},{
   max_stanza_size,65536}]},
 {
   {5269,{0,0,0,0},tcp},ejabberd_s2s_in,[]},
 {
   {5280,{0,0,0,0},tcp},
  ejabberd_http,
  [{
   captcha,true},
   {
   http_bind,true},
   {
   web_admin,true},
   {
   request_handlers,[{<<"/websocket">>,ejabberd_http_ws}]}]}]

继续跟踪

bind_tcp_port(PortIP, Module, RawOpts) ->
    try check_listener_options(RawOpts) of
    ok ->
        {
  Port, IPT, IPS, IPV, Proto, OptsClean} = parse_listener_portip(PortIP, RawOpts),
        {_Opts, SockOpts} = prepare_opts(IPT, IPV, OptsClean),
        case Proto of
        udp -> ok;
        _ ->
            %%%TCP
            ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS),
            %%%监听端口成功,插入listen_sockets表
            ets:insert(listen_sockets, {
  PortIP, ListenSocket}),
                    ok
        end
    catch
    throw:{error, Error} ->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值