entryHandler.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2015 rain1017.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License. See the AUTHORS file
  14. // for names of contributors.
  15. 'use strict';
  16. var util = require('util');
  17. var quick = require('quick-pomelo');
  18. var P = quick.Promise;
  19. var logger = quick.logger.getLogger('connector', __filename);
  20. var Handler = function(app){
  21. this.app = app;
  22. };
  23. var proto = Handler.prototype;
  24. var authFunc = function(token){
  25. //TODO: authentication;
  26. return token;
  27. };
  28. /**
  29. * msg.auth - authentication data
  30. */
  31. proto.login = function(msg, session, next){
  32. if(!!session.uid){
  33. return next(new Error('session already logged in with playerId ' + session.uid));
  34. }
  35. var token = msg.token;
  36. if(!token){
  37. return next(new Error('token is missing'));
  38. }
  39. var playerId = null;
  40. return P.bind(this)
  41. .then(function(){
  42. return authFunc(token);
  43. })
  44. .then(function(ret){
  45. playerId = ret;
  46. if(!playerId){
  47. throw new Error('Invalid token: ' + token);
  48. }
  49. })
  50. .then(function(){
  51. return this.app.controllers.player.connectAsync(playerId, session.frontendId);
  52. })
  53. .then(function(ret){
  54. var oldConnectorId = ret.oldConnectorId;
  55. if(oldConnectorId){
  56. logger.warn('player %s already connected on %s, will kick', playerId, oldConnectorId);
  57. // kick original connector
  58. var entryRemote = this.app.rpc.connector.entryRemote;
  59. return P.promisify(entryRemote.kick, entryRemote)({frontendId : oldConnectorId}, playerId);
  60. }
  61. })
  62. .then(function(){
  63. return this.app.reqIdFilter.getReqId(playerId);
  64. })
  65. .then(function(reqId){
  66. var self = this;
  67. return P.promisify(session.bind, session)(playerId)
  68. .then(function(){
  69. // OnDisconnect
  70. session.on('closed', function(session, reason){
  71. if(reason === 'kick' || !session.uid){
  72. return;
  73. }
  74. // auto logout on disconnect
  75. var goose = self.app.memdb.goose;
  76. goose.transaction(function(){
  77. return P.promisify(self.logout, self)({closed : true}, session);
  78. }, self.app.getServerId())
  79. .catch(function(e){
  80. logger.error(e.stack);
  81. });
  82. });
  83. logger.info('player %s login', playerId);
  84. return {reqId : reqId};
  85. });
  86. })
  87. .nodeify(next);
  88. };
  89. proto.logout = function(msg, session, next){
  90. var playerId = session.uid;
  91. if(!playerId){
  92. return next(new Error('playerId is missing'));
  93. }
  94. P.bind(this)
  95. .then(function(){
  96. return this.app.controllers.player.disconnectAsync(playerId);
  97. })
  98. .then(function(){
  99. if(!msg.closed){
  100. return P.promisify(session.unbind, session)(playerId);
  101. }
  102. })
  103. .then(function(){
  104. logger.info('player %s logout', playerId);
  105. })
  106. .nodeify(next);
  107. };
  108. module.exports = function(app){
  109. return new Handler(app);
  110. };