PageRenderTime 57ms CodeModel.GetById 6ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/socket.js

https://github.com/lucciano/zerorpc-node
JavaScript | 145 lines | 73 code | 23 blank | 49 comment | 8 complexity | 6672e94cb3679caa7ab3b9938861e1ca MD5 | raw file
  1. // Open Source Initiative OSI - The MIT License (MIT):Licensing
  2. //
  3. // The MIT License (MIT)
  4. // Copyright (c) 2012 DotCloud Inc (opensource@dotcloud.com)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a
  7. // copy of this software and associated documentation files (the "Software"),
  8. // to deal in the Software without restriction, including without limitation
  9. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. // and/or sell copies of the Software, and to permit persons to whom the
  11. // Software is furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. // DEALINGS IN THE SOFTWARE.
  23. var nodeUtil = require("util"),
  24. zmq = require("zmq"),
  25. nodeEvents = require("events"),
  26. events = require("./events"),
  27. util = require("./util"),
  28. channel = require("./channel");
  29. //The default channel capacity
  30. var CHANNEL_CAPACITY = 100;
  31. //Creates a new socket
  32. //zmqSocket : Object
  33. // The underlying ZeroMQ socket to use
  34. function Socket(zmqSocket) {
  35. var self = this;
  36. self._zmqSocket = zmqSocket;
  37. util.eventProxy(self._zmqSocket, self, "error");
  38. var error = function(message) {
  39. self.emit("error", message);
  40. };
  41. self._zmqSocket.on("message", function() {
  42. //Deserialize the object and perform some sanity checks
  43. if(arguments[arguments.length - 2].length != 0) {
  44. return error("Expected second to last argument to be an empty buffer, but it is not");
  45. }
  46. var envelope = Array.prototype.slice.call(arguments, 0, arguments.length - 2);
  47. try {
  48. var event = events.deserialize(envelope, arguments[arguments.length - 1]);
  49. } catch(e) {
  50. return error("Invalid event: " + e);
  51. }
  52. //Emit the event
  53. self.emit("socket/receive", event);
  54. });
  55. }
  56. nodeUtil.inherits(Socket, nodeEvents.EventEmitter);
  57. //Sends a message on the socket
  58. //event : Object
  59. // The ZeroRPC event to send
  60. Socket.prototype.send = function(event) {
  61. var message = events.serialize(event);
  62. this._zmqSocket.send.call(this._zmqSocket, message);
  63. };
  64. //Binds to a ZeroMQ endpoint
  65. //endpoint : String
  66. // The ZeroMQ endpoint
  67. Socket.prototype.bind = function(endpoint) {
  68. this._zmqSocket.bindSync(endpoint);
  69. }
  70. //Connects to a ZeroMQ endpoint
  71. //endpoint : String
  72. // The ZeroMQ endpoint
  73. Socket.prototype.connect = function(endpoint) {
  74. this._zmqSocket.connect(endpoint);
  75. }
  76. //Creates a new multiplexing socket
  77. //zmqSocket : Object
  78. // The underlying ZeroMQ socket to use
  79. function MultiplexingSocket(zmqSocket) {
  80. Socket.call(this, zmqSocket);
  81. var self = this;
  82. //Map of open channel IDs => channel objects
  83. self.channels = {};
  84. //Route events to a channel if possible; otherwise emit the event
  85. self.on("socket/receive", function(event) {
  86. var ch = self.channels[event.header.response_to || ""];
  87. if(ch) {
  88. ch.invoke(event);
  89. } else {
  90. self.emit("multiplexing-socket/receive", event);
  91. }
  92. });
  93. }
  94. nodeUtil.inherits(MultiplexingSocket, Socket);
  95. //Opens a new channel
  96. //srcEvent : Object or null
  97. // The ZeroRPC event that caused the channel to be opened, or null if
  98. // this is a locally opened channel.
  99. MultiplexingSocket.prototype.openChannel = function(srcEvent) {
  100. if(srcEvent) {
  101. var ch = new channel.ServerChannel(srcEvent, this, CHANNEL_CAPACITY);
  102. } else {
  103. var ch = new channel.ClientChannel(this, CHANNEL_CAPACITY);
  104. }
  105. this.channels[ch.id] = ch;
  106. return ch;
  107. };
  108. //Closes the socket
  109. MultiplexingSocket.prototype.close = function() {
  110. this._zmqSocket.close();
  111. for(var id in this.channels) this.channels[id].close();
  112. };
  113. //Creates a new multiplexing socket server
  114. function server() {
  115. return new MultiplexingSocket(zmq.socket("xrep"));
  116. }
  117. //Creates a new multiplexing socket client
  118. function client() {
  119. return new MultiplexingSocket(zmq.socket("xreq"));
  120. }
  121. exports.server = server;
  122. exports.client = client;