handshake.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. var pomelo = require('../../pomelo');
  2. var Package = require('pomelo-protocol').Package;
  3. var CODE_OK = 200;
  4. var CODE_USE_ERROR = 500;
  5. var CODE_OLD_CLIENT = 501;
  6. /**
  7. * Process the handshake request.
  8. *
  9. * @param {Object} opts option parameters
  10. * opts.handshake(msg, cb(err, resp)) handshake callback. msg is the handshake message from client.
  11. * opts.hearbeat heartbeat interval (level?)
  12. * opts.version required client level
  13. */
  14. var Command = function(opts) {
  15. opts = opts || {};
  16. this.userHandshake = opts.handshake;
  17. if(opts.heartbeat) {
  18. this.heartbeatSec = opts.heartbeat;
  19. this.heartbeat = opts.heartbeat * 1000;
  20. }
  21. this.checkClient = opts.checkClient;
  22. this.useDict = opts.useDict;
  23. this.useProtobuf = opts.useProtobuf;
  24. this.useCrypto = opts.useCrypto;
  25. };
  26. module.exports = Command;
  27. Command.prototype.handle = function(socket, msg) {
  28. if(!msg.sys) {
  29. processError(socket, CODE_USE_ERROR);
  30. return;
  31. }
  32. if(typeof this.checkClient === 'function') {
  33. if(!msg || !msg.sys || !this.checkClient(msg.sys.type, msg.sys.version)) {
  34. processError(socket, CODE_OLD_CLIENT);
  35. return;
  36. }
  37. }
  38. var opts = {
  39. heartbeat : setupHeartbeat(this)
  40. };
  41. if(this.useDict) {
  42. var dictVersion = pomelo.app.components.__dictionary__.getVersion();
  43. if(!msg.sys.dictVersion || msg.sys.dictVersion !== dictVersion){
  44. // may be deprecated in future
  45. opts.dict = pomelo.app.components.__dictionary__.getDict();
  46. opts.routeToCode = pomelo.app.components.__dictionary__.getDict();
  47. opts.codeToRoute = pomelo.app.components.__dictionary__.getAbbrs();
  48. opts.dictVersion = dictVersion;
  49. }
  50. opts.useDict = true;
  51. }
  52. if(this.useProtobuf) {
  53. var protoVersion = pomelo.app.components.__protobuf__.getVersion();
  54. if(!msg.sys.protoVersion || msg.sys.protoVersion !== protoVersion){
  55. opts.protos = pomelo.app.components.__protobuf__.getProtos();
  56. }
  57. opts.useProto = true;
  58. }
  59. if(!!pomelo.app.components.__decodeIO__protobuf__) {
  60. if(!!this.useProtobuf) {
  61. throw new Error('protobuf can not be both used in the same project.');
  62. }
  63. var version = pomelo.app.components.__decodeIO__protobuf__.getVersion();
  64. if(!msg.sys.protoVersion || msg.sys.protoVersion < version) {
  65. opts.protos = pomelo.app.components.__decodeIO__protobuf__.getProtos();
  66. }
  67. opts.useProto = true;
  68. }
  69. if(this.useCrypto) {
  70. pomelo.app.components.__connector__.setPubKey(socket.id, msg.sys.rsa);
  71. }
  72. if(typeof this.userHandshake === 'function') {
  73. this.userHandshake(msg, function(err, resp) {
  74. if(err) {
  75. process.nextTick(function() {
  76. processError(socket, CODE_USE_ERROR);
  77. });
  78. return;
  79. }
  80. process.nextTick(function() {
  81. response(socket, opts, resp);
  82. });
  83. }, socket);
  84. return;
  85. }
  86. process.nextTick(function() {
  87. response(socket, opts);
  88. });
  89. };
  90. var setupHeartbeat = function(self) {
  91. return self.heartbeatSec;
  92. };
  93. var response = function(socket, sys, resp) {
  94. var res = {
  95. code: CODE_OK,
  96. sys: sys
  97. };
  98. if(resp) {
  99. res.user = resp;
  100. }
  101. socket.handshakeResponse(Package.encode(Package.TYPE_HANDSHAKE, new Buffer(JSON.stringify(res))));
  102. };
  103. var processError = function(socket, code) {
  104. var res = {
  105. code: code
  106. };
  107. socket.sendForce(Package.encode(Package.TYPE_HANDSHAKE, new Buffer(JSON.stringify(res))));
  108. process.nextTick(function() {
  109. socket.disconnect();
  110. });
  111. };