You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.0 KiB

  1. #!/usr/bin/env node
  2. /*!
  3. * ws: a node.js websocket client
  4. * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
  5. * MIT Licensed
  6. */
  7. /**
  8. * Module dependencies.
  9. */
  10. var WebSocket = require('../')
  11. , fs = require('fs')
  12. , program = require('commander')
  13. , util = require('util')
  14. , events = require('events')
  15. , readline = require('readline');
  16. /**
  17. * InputReader - processes console input
  18. */
  19. function Console() {
  20. this.stdin = process.stdin;
  21. this.stdout = process.stdout;
  22. this.readlineInterface = readline.createInterface(this.stdin, this.stdout);
  23. var self = this;
  24. this.readlineInterface.on('line', function(data) {
  25. self.emit('line', data);
  26. });
  27. this.readlineInterface.on('close', function() {
  28. self.emit('close');
  29. });
  30. this._resetInput = function() {
  31. self.clear();
  32. }
  33. }
  34. util.inherits(Console, events.EventEmitter);
  35. Console.Colors = {
  36. Red: '\033[31m',
  37. Green: '\033[32m',
  38. Yellow: '\033[33m',
  39. Blue: '\033[34m',
  40. Default: '\033[39m'
  41. };
  42. Console.prototype.prompt = function() {
  43. this.readlineInterface.prompt();
  44. }
  45. Console.prototype.print = function(msg, color) {
  46. this.clear();
  47. color = color || Console.Colors.Default;
  48. this.stdout.write(color + msg + Console.Colors.Default + '\n');
  49. this.prompt();
  50. }
  51. Console.prototype.clear = function() {
  52. this.stdout.write('\033[2K\033[E');
  53. }
  54. Console.prototype.pause = function() {
  55. this.stdin.on('keypress', this._resetInput);
  56. }
  57. Console.prototype.resume = function() {
  58. this.stdin.removeListener('keypress', this._resetInput);
  59. }
  60. /**
  61. * The actual application
  62. */
  63. var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json', 'utf8')).version;
  64. program
  65. .version(version)
  66. .usage('[options] <url>')
  67. .option('-l, --listen <port>', 'listen on port')
  68. .option('-c, --connect <url>', 'connect to a websocket server')
  69. .option('-p, --protocol <version>', 'optional protocol version')
  70. .option('-o, --origin <origin>', 'optional origin')
  71. .option('--host <host>', 'optional host')
  72. .option('-s, --subprotocol <protocol>', 'optional subprotocol')
  73. .parse(process.argv);
  74. if (program.listen && program.connect) {
  75. console.error('\033[33merror: use either --listen or --connect\033[39m');
  76. process.exit(-1);
  77. }
  78. else if (program.listen) {
  79. var wsConsole = new Console();
  80. wsConsole.pause();
  81. var options = {};
  82. if (program.protocol) options.protocolVersion = program.protocol;
  83. if (program.origin) options.origin = program.origin;
  84. if (program.subprotocol) options.protocol = program.subprotocol;
  85. var ws = null;
  86. var wss = new WebSocket.Server({port: program.listen}, function() {
  87. wsConsole.print('listening on port ' + program.listen + ' (press CTRL+C to quit)', Console.Colors.Green);
  88. wsConsole.clear();
  89. });
  90. wsConsole.on('close', function() {
  91. if (ws) {
  92. try {
  93. ws.close();
  94. }
  95. catch (e) {}
  96. }
  97. process.exit(0);
  98. });
  99. wsConsole.on('line', function(data) {
  100. if (ws) {
  101. ws.send(data, {mask: false});
  102. wsConsole.prompt();
  103. }
  104. });
  105. wss.on('connection', function(newClient) {
  106. if (ws) {
  107. // limit to one client
  108. newClient.terminate();
  109. return;
  110. };
  111. ws = newClient;
  112. wsConsole.resume();
  113. wsConsole.prompt();
  114. wsConsole.print('client connected', Console.Colors.Green);
  115. ws.on('close', function() {
  116. wsConsole.print('disconnected', Console.Colors.Green);
  117. wsConsole.clear();
  118. wsConsole.pause();
  119. ws = null;
  120. });
  121. ws.on('error', function(code, description) {
  122. wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow);
  123. });
  124. ws.on('message', function(data, flags) {
  125. wsConsole.print('< ' + data, Console.Colors.Blue);
  126. });
  127. });
  128. wss.on('error', function(error) {
  129. wsConsole.print('error: ' + error.toString(), Console.Colors.Yellow);
  130. process.exit(-1);
  131. });
  132. }
  133. else if (program.connect) {
  134. var wsConsole = new Console();
  135. var options = {};
  136. if (program.protocol) options.protocolVersion = program.protocol;
  137. if (program.origin) options.origin = program.origin;
  138. if (program.subprotocol) options.protocol = program.subprotocol;
  139. if (program.host) options.host = program.host;
  140. var ws = new WebSocket(program.connect, options);
  141. ws.on('open', function() {
  142. wsConsole.print('connected (press CTRL+C to quit)', Console.Colors.Green);
  143. wsConsole.on('line', function(data) {
  144. ws.send(data, {mask: true});
  145. wsConsole.prompt();
  146. });
  147. });
  148. ws.on('close', function() {
  149. wsConsole.print('disconnected', Console.Colors.Green);
  150. wsConsole.clear();
  151. process.exit();
  152. });
  153. ws.on('error', function(code, description) {
  154. wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow);
  155. process.exit(-1);
  156. });
  157. ws.on('message', function(data, flags) {
  158. wsConsole.print('< ' + data, Console.Colors.Blue);
  159. });
  160. wsConsole.on('close', function() {
  161. if (ws) {
  162. try {
  163. ws.close();
  164. }
  165. catch(e) {}
  166. process.exit();
  167. }
  168. });
  169. }
  170. else {
  171. console.error('\033[33merror: use either --listen or --connect\033[39m');
  172. process.exit(-1);
  173. }