handshake.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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(typeof this.checkClient === 'function') {
  29. if(!msg || !msg.sys || !this.checkClient(msg.sys.type, msg.sys.version)) {
  30. processError(socket, CODE_OLD_CLIENT);
  31. return;
  32. }
  33. }
  34. var opts = {
  35. heartbeat : setupHeartbeat(this)
  36. };
  37. if(this.useDict) {
  38. var dictVersion = pomelo.app.components.__dictionary__.getVersion();
  39. if(!msg.sys.dictVersion || msg.sys.dictVersion !== dictVersion){
  40. // may be deprecated in future
  41. opts.dict = pomelo.app.components.__dictionary__.getDict();
  42. opts.routeToCode = pomelo.app.components.__dictionary__.getDict();
  43. opts.codeToRoute = pomelo.app.components.__dictionary__.getAbbrs();
  44. opts.dictVersion = dictVersion;
  45. }
  46. opts.useDict = true;
  47. }
  48. if(this.useProtobuf) {
  49. var protoVersion = pomelo.app.components.__protobuf__.getVersion();
  50. if(!msg.sys.protoVersion || msg.sys.protoVersion !== protoVersion){
  51. opts.protos = pomelo.app.components.__protobuf__.getProtos();
  52. }
  53. opts.useProto = true;
  54. }
  55. if(!!pomelo.app.components.__decodeIO__protobuf__) {
  56. if(!!this.useProtobuf) {
  57. throw new Error('protobuf can not be both used in the same project.');
  58. }
  59. var version = pomelo.app.components.__decodeIO__protobuf__.getVersion();
  60. if(!msg.sys.protoVersion || msg.sys.protoVersion < version) {
  61. opts.protos = pomelo.app.components.__decodeIO__protobuf__.getProtos();
  62. }
  63. opts.useProto = true;
  64. }
  65. if(this.useCrypto) {
  66. pomelo.app.components.__connector__.setPubKey(socket.id, msg.sys.rsa);
  67. }
  68. if(typeof this.userHandshake === 'function') {
  69. this.userHandshake(msg, function(err, resp) {
  70. if(err) {
  71. process.nextTick(function() {
  72. processError(socket, CODE_USE_ERROR);
  73. });
  74. return;
  75. }
  76. process.nextTick(function() {
  77. response(socket, opts, resp);
  78. });
  79. });
  80. return;
  81. }
  82. process.nextTick(function() {
  83. response(socket, opts);
  84. });
  85. };
  86. var setupHeartbeat = function(self) {
  87. return self.heartbeatSec;
  88. };
  89. var response = function(socket, sys, resp) {
  90. var res = {
  91. code: CODE_OK,
  92. sys: sys
  93. };
  94. if(resp) {
  95. res.user = resp;
  96. }
  97. socket.handshakeResponse(Package.encode(Package.TYPE_HANDSHAKE, new Buffer(JSON.stringify(res))));
  98. };
  99. var processError = function(socket, code) {
  100. var res = {
  101. code: code
  102. };
  103. socket.sendForce(Package.encode(Package.TYPE_HANDSHAKE, new Buffer(JSON.stringify(res))));
  104. process.nextTick(function() {
  105. socket.disconnect();
  106. });
  107. };