tcp-node.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. "use strict";
  2. var makeChannel = require('culvert');
  3. var wrapHandler = require('../lib/wrap-handler');
  4. var net = require('net');
  5. module.exports = connect;
  6. function connect(host, port, onError) {
  7. port = port|0;
  8. host = String(host);
  9. if (!port || !host) throw new TypeError("host and port are required");
  10. // Wrap event handlers from node stream
  11. onConnect = wrap(onConnect, onError);
  12. pump = wrap(pump, onError);
  13. onEnd = wrap(onEnd, onError);
  14. onDrain = wrap(onDrain, onError);
  15. // Wrap event handlers from culvert socket
  16. onTake = wrapHandler(onTake, onError);
  17. var serverChannel = makeChannel();
  18. var clientChannel = makeChannel();
  19. var socket = {
  20. put: serverChannel.put,
  21. drain: serverChannel.drain,
  22. take: clientChannel.take
  23. };
  24. var client = net.connect({ host: host, port: port }, onConnect);
  25. if (onError) client.on("error", onError);
  26. return {
  27. put: clientChannel.put,
  28. drain: clientChannel.drain,
  29. take: serverChannel.take
  30. };
  31. function onConnect() {
  32. socket.take(onTake);
  33. client.on("end", onEnd);
  34. client.on("readable", pump);
  35. client.on("drain", onDrain);
  36. client.on("error", onError);
  37. }
  38. function pump() {
  39. var chunk;
  40. do {
  41. chunk = client.read();
  42. if (!chunk) return;
  43. } while (socket.put(chunk));
  44. socket.drain(pump);
  45. }
  46. function onEnd() {
  47. socket.put();
  48. }
  49. function onTake(data) {
  50. if (data === undefined) {
  51. client.end();
  52. }
  53. else if (client.write(data)) {
  54. socket.take(onTake);
  55. }
  56. }
  57. function onDrain() {
  58. socket.take(onTake);
  59. }
  60. }
  61. function wrap(fn, onError) {
  62. return function () {
  63. try {
  64. return fn.apply(this, arguments);
  65. }
  66. catch (err) {
  67. onError(err);
  68. }
  69. };
  70. }