pomelo源碼分析(7)--connector與其它組件交互

作者:shihuaping0918@163.com,轉(zhuǎn)載請(qǐng)注明作者

connector是一個(gè)重量級(jí)組件,它依賴connection/server/pushScheduler/session組件。
對(duì)session組件的依賴是對(duì)連接創(chuàng)建一個(gè)session。
對(duì)connection的依賴是連接數(shù)的增加減少辐脖,以及登錄用戶uid的管理。
對(duì)pushScheduler的依賴是皆愉,當(dāng)異步發(fā)送時(shí)嗜价,把發(fā)送任務(wù)放到scheduler里艇抠。
對(duì)server的依賴就是取一些配置,以及server本身的信息久锥。

下面依次對(duì)它們進(jìn)行介紹家淤。首先從session開始,session和connection的依賴代碼有一部分是在一起的。

/**
 * get session for current connection
 */
var getSession = function(self, socket) {
  var app = self.app,
    sid = socket.id;
  var session = self.session.get(sid);  //sid
  if (session) {
    return session;
  }
  //這里創(chuàng)建一個(gè)session,
  session = self.session.create(sid, app.getServerId(), socket);
  logger.debug('[%s] getSession session is created with session id: %s', app.getServerId(), sid);

  // bind events for session
  socket.on('disconnect', session.closed.bind(session));
  socket.on('error', session.closed.bind(session));
  session.on('closed', onSessionClose.bind(null, app));
  session.on('bind', function(uid) {
    logger.debug('session on [%s] bind with uid: %s', self.app.serverId, uid);
    // update connection statistics if necessary
    if (self.connection) {
    //添加用戶到connection中
      self.connection.addLoginedUser(uid, {
        loginTime: Date.now(),
        uid: uid,
        address: socket.remoteAddress.ip + ':' + socket.remoteAddress.port
      });
    }
    self.app.event.emit(events.BIND_SESSION, session);
  });

  session.on('unbind', function(uid) {
    if (self.connection) {
      //從connection中移除用戶
      self.connection.removeLoginedUser(uid);
    }
    self.app.event.emit(events.UNBIND_SESSION, session);
  });

  return session;
};

getSession這個(gè)函數(shù)是在 var bindEvents = function(self, socket)這個(gè)函數(shù)里調(diào)用的。它的主要工作就是給事件綁定回調(diào)函數(shù)碴开。和session有關(guān)的就是創(chuàng)建session了。和connection有關(guān)的就是添加用戶和移除用戶青伤。session真正的實(shí)現(xiàn)都在service/sessionService.js里面。component/session.js只是一個(gè)抽象殴瘦。對(duì)connection也是同理狠角。

再來看一下pushScheduler是怎么被調(diào)用的,這里不涉及pushScheduler的內(nèi)部機(jī)制蚪腋,只看connector調(diào)用了它哪些接口丰歌。


pro.send = function(reqId, route, msg, recvs, opts, cb) {
  logger.debug('[%s] send message reqId: %s, route: %s, msg: %j, receivers: %j, opts: %j', this.app.serverId, reqId, route, msg, recvs, opts);
  if (this.useAsyncCoder) {
    return this.sendAsync(reqId, route, msg, recvs, opts, cb);
  }

  var emsg = msg;
  if (this.encode) {
    // use costumized encode
    emsg = this.encode.call(this, reqId, route, msg);
  } else if (this.connector.encode) {
    // use connector default encode
    emsg = this.connector.encode(reqId, route, msg);
  }

  this.doSend(reqId, route, emsg, recvs, opts, cb);
};

pro.sendAsync = function(reqId, route, msg, recvs, opts, cb) {
  var emsg = msg;
  var self = this;

  if (this.encode) {
    // use costumized encode
    this.encode(reqId, route, msg, function(err, encodeMsg) {
      if (err) {
        return cb(err);
      }

      emsg = encodeMsg;
      self.doSend(reqId, route, emsg, recvs, opts, cb);
    });
  } else if (this.connector.encode) {
    // use connector default encode
    this.connector.encode(reqId, route, msg, function(err, encodeMsg) {
      if (err) {
        return cb(err);
      }

      emsg = encodeMsg;
      self.doSend(reqId, route, emsg, recvs, opts, cb);
    });
  }
}

pro.doSend = function(reqId, route, emsg, recvs, opts, cb) {
  if (!emsg) {
    process.nextTick(function() {
      return cb && cb(new Error('fail to send message for encode result is empty.'));
    });
  }
  //只需要關(guān)注這里就可以了
  this.app.components.__pushScheduler__.schedule(reqId, route, emsg,
    recvs, opts, cb);
}

send和sendAsync的區(qū)別不是表現(xiàn)在網(wǎng)絡(luò)發(fā)送上,而是在編碼上屉凯,代碼中最終網(wǎng)絡(luò)發(fā)送調(diào)的都是doSend立帖。把要發(fā)的內(nèi)容放到sheduler里面去,在里面進(jìn)行真正的發(fā)送操作神得。

最后看一下對(duì)server的依賴厘惦,connector對(duì)server的依賴表現(xiàn)在取一些配置信息上。比如要綁定的host/port哩簿。

var getConnector = function(app, opts) {
  var connector = opts.connector;
  if (!connector) {
    return getDefaultConnector(app, opts);
  }

  if (typeof connector !== 'function') {
    return connector;
  }
  //就是這里了
  var curServer = app.getCurServer();
  //取clientPort,host
  return connector(curServer.clientPort, curServer.host, opts);
};

另外還有一個(gè)依賴就是要調(diào)用server中的handler對(duì)消息進(jìn)行處理。

  self.server.globalHandle(msg, session.toFrontendSession(), function(err, resp, opts) {

對(duì)connector本身的分析到這里就算是基本完成了酝静,但是又留下了更多的疑問节榜。其中session/connection還比較好理解。而scheduler和server理解起來就是有一定困難的别智。后續(xù)會(huì)慢慢講到宗苍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市薄榛,隨后出現(xiàn)的幾起案子讳窟,更是在濱河造成了極大的恐慌,老刑警劉巖敞恋,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丽啡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡硬猫,警方通過查閱死者的電腦和手機(jī)补箍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門改执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坑雅,你說我怎么就攤上這事辈挂。” “怎么了裹粤?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵终蒂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我遥诉,道長(zhǎng)拇泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任突那,我火速辦了婚禮挫酿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘愕难。我一直安慰自己早龟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布猫缭。 她就那樣靜靜地躺著葱弟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猜丹。 梳的紋絲不亂的頭發(fā)上芝加,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音射窒,去河邊找鬼藏杖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脉顿,可吹牛的內(nèi)容都是我干的蝌麸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼艾疟,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼来吩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔽莱,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤弟疆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盗冷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怠苔,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年正塌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘀略。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恤溶。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖帜羊,靈堂內(nèi)的尸體忽然破棺而出咒程,到底是詐尸還是另有隱情,我是刑警寧澤讼育,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布帐姻,位于F島的核電站,受9級(jí)特大地震影響奶段,放射性物質(zhì)發(fā)生泄漏饥瓷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一痹籍、第九天 我趴在偏房一處隱蔽的房頂上張望呢铆。 院中可真熱鬧,春花似錦蹲缠、人聲如沸棺克。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娜谊。三九已至,卻和暖如春斤讥,著一層夾襖步出監(jiān)牢的瞬間纱皆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工芭商, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留派草,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓铛楣,卻偏偏與公主長(zhǎng)得像澳眷,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛉艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)衷敌,斷路器勿侯,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評(píng)論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法缴罗,內(nèi)部類的語法助琐,繼承相關(guān)的語法,異常的語法面氓,線程的語...
    子非魚_t_閱讀 31,635評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在兵钮,面了一些公司蛆橡,掛了不少,但最終還是拿到小米掘譬、百度泰演、阿里、京東葱轩、新浪睦焕、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,251評(píng)論 11 349
  • 一只貓誤入了一群狗之間靴拱。 貓:hello垃喊? 狗:汪~ 貓:Excuse me? 狗:嗷嗚~ 貓:這他喵的說的啥袜炕? ...
    三無油煙機(jī)閱讀 155評(píng)論 0 0