title: amqplib: Socket closed abruptly during opening handshake
body: <h1>What I am trying to do</h1>
  
  <p>I try to create rabbit-mq publisher &amp; subscriber. It works as expected until I try to restart my rabbit-mq server.</p>
  
  <h1>What works</h1>
  
  <p>I use <code>rabbitmq:3-management</code> docker image, <code>ampqlib 5.3</code>, and Node.js <code>11.10.0</code> to make this simple program:</p>
  
  <pre><code>const q = 'tasks';
  
  const { execSync } = require("child_process");
  const amqplib = require("amqplib");
  
  function createChannel() {
      return amqplib.connect("amqp://root:toor@0.0.0.0:5672/")
          .then((conn) =&gt; conn.createChannel());
  }
  
  Promise.all([createChannel(), createChannel()])
  
      .then(async (channels) =&gt; {
          const [publisherChannel, consumerChannel] = channels;
  
          // publisher
          await publisherChannel.assertQueue(q).then(function(ok) {
              return publisherChannel.sendToQueue(q, Buffer.from("something to do"));
          });
  
          // consumer
          await consumerChannel.assertQueue(q).then(function(ok) {
              return consumerChannel.consume(q, function(msg) {
                  if (msg !== null) {
                      console.log(msg.content.toString());
                      consumerChannel.ack(msg);
                  }
              });
          });
  
      })
  
      .catch(console.warn);
  
  </code></pre>
  
  <p>So, first of all, I made two channels. One as publisher, and the other as consumer.</p>
  
  <p>The publisher emit <code>something to do</code> message to <code>tasks</code> queue.</p>
  
  <p>The consumer then catch the message and print it to the screen using <code>console.log</code>.</p>
  
  <p>It works as expected.</p>
  
  <h1>What doesn't work</h1>
  
  <h2>First Attempt</h2>
  
  <pre><code>const q = 'tasks';
  
  const { execSync } = require("child_process");
  const amqplib = require("amqplib");
  
  function createChannel() {
      return amqplib.connect("amqp://root:toor@0.0.0.0:5672/")
          .then((conn) =&gt; conn.createChannel());
  }
  
  Promise.all([createChannel(), createChannel()])
  
      .then((channels) =&gt; {
  
          // Let's say rabbitmq is down, and then up again
          execSync("docker stop rabbitmq");
          execSync("docker start rabbitmq");
  
          return channels;
      })
  
      .then(async (channels) =&gt; {
          const [publisherChannel, consumerChannel] = channels;
  
          // publisher
          await publisherChannel.assertQueue(q).then(function(ok) {
              return publisherChannel.sendToQueue(q, Buffer.from("something to do"));
          });
  
          // consumer
          await consumerChannel.assertQueue(q).then(function(ok) {
              return consumerChannel.consume(q, function(msg) {
                  if (msg !== null) {
                      console.log(msg.content.toString());
                      consumerChannel.ack(msg);
                  }
              });
          });
  
      })
  
      .catch(console.warn);
  </code></pre>
  
  <p>Similar to my previous attempt, but this time I try to stop and start rabbit-mq container (restarting the server) before proceed.</p>
  
  <p>It doesn't work, I get this error instead:</p>
  
  <pre><code>{ Error: Socket closed abruptly during opening handshake
      at Socket.endWhileOpening (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:260:17)                                                           
      at Socket.emit (events.js:202:15)
      at endReadableNT (_stream_readable.js:1129:12)
      at processTicksAndRejections (internal/process/next_tick.js:76:17)
    cause:
     Error: Socket closed abruptly during opening handshake
         at Socket.endWhileOpening (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:260:17)                                                        
         at Socket.emit (events.js:202:15)
         at endReadableNT (_stream_readable.js:1129:12)
         at processTicksAndRejections (internal/process/next_tick.js:76:17),
    isOperational: true }
  [guldan@draenor labs]$ node --version
  v11.10.0
  [guldan@draenor labs]$ docker start rabbitmq &amp;&amp; node test.js
  rabbitmq
  { Error: Channel ended, no reply will be forthcoming
      at rej (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:195:7)                                                                                  
      at Channel.C._rejectPending (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:197:28)                                                            
      at Channel.C.toClosed (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:165:8)                                                                   
      at Connection.C._closeChannels (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:394:18)                                                      
      at Connection.C.toClosed (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:401:8)                                                             
      at Object.accept (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:96:18)                                                                     
      at Connection.mainAccept [as accept] (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:64:33)                                                 
      at Socket.go (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:478:48)                                                                        
      at Socket.emit (events.js:197:13)
      at emitReadable_ (_stream_readable.js:539:12)
      at processTicksAndRejections (internal/process/next_tick.js:76:17)
    cause:
     Error: Channel ended, no reply will be forthcoming
         at rej (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:195:7)                                                                               
         at Channel.C._rejectPending (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:197:28)                                                         
         at Channel.C.toClosed (/home/guldan/Projects/node_modules/amqplib/lib/channel.js:165:8)                                                                
         at Connection.C._closeChannels (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:394:18)                                                   
         at Connection.C.toClosed (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:401:8)                                                          
         at Object.accept (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:96:18)                                                                  
         at Connection.mainAccept [as accept] (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:64:33)                                              
         at Socket.go (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:478:48)                                                                     
         at Socket.emit (events.js:197:13)
         at emitReadable_ (_stream_readable.js:539:12)
         at processTicksAndRejections (internal/process/next_tick.js:76:17),
    isOperational: true }
  </code></pre>
  
  <h2>Second attempt</h2>
  
  <p>My first attempt didn't work. So, I try to create new channel after restarting the server:</p>
  
  <pre><code>const q = 'tasks';
  
  const { execSync } = require("child_process");
  const amqplib = require("amqplib");
  
  function createChannel() {
      return amqplib.connect("amqp://root:toor@0.0.0.0:5672/")
          .then((conn) =&gt; conn.createChannel());
  }
  
  Promise.all([createChannel(), createChannel()])
  
      .then((channels) =&gt; {
  
          // Let's say rabbitmq is down, and then up again
          execSync("docker stop rabbitmq");
          execSync("docker start rabbitmq");
  
          return Promise.all([createChannel(), createChannel()]);
          // return channels;
      })
  
      .then(async (channels) =&gt; {
          const [publisherChannel, consumerChannel] = channels;
  
          // publisher
          await publisherChannel.assertQueue(q).then(function(ok) {
              return publisherChannel.sendToQueue(q, Buffer.from("something to do"));
          });
  
          // consumer
          await consumerChannel.assertQueue(q).then(function(ok) {
              return consumerChannel.consume(q, function(msg) {
                  if (msg !== null) {
                      console.log(msg.content.toString());
                      consumerChannel.ack(msg);
                  }
              });
          });
  
      })
  
      .catch(console.warn);
  
  </code></pre>
  
  <p>And this time, I got this error instead:</p>
  
  <pre><code>{ Error: Socket closed abruptly during opening handshake
      at Socket.endWhileOpening (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:260:17)                                                           
      at Socket.emit (events.js:202:15)
      at endReadableNT (_stream_readable.js:1129:12)
      at processTicksAndRejections (internal/process/next_tick.js:76:17)
    cause:
     Error: Socket closed abruptly during opening handshake
         at Socket.endWhileOpening (/home/guldan/Projects/node_modules/amqplib/lib/connection.js:260:17)                                                        
         at Socket.emit (events.js:202:15)
         at endReadableNT (_stream_readable.js:1129:12)
         at processTicksAndRejections (internal/process/next_tick.js:76:17),
    isOperational: true }
  
  </code></pre>
  
  <p>I'm not really sure, but I think the error is related to It might be related to <a href="https://github.com/squaremo/amqp.node/issues/101" rel="nofollow noreferrer">https://github.com/squaremo/amqp.node/issues/101</a>.</p>
  
  <h1>What I want</h1>
  
  <p>I want workaround/solution to reconnect to rabbitmq after the server restarted. Any explanation/suggestion is also welcomed.</p>
  
  <h1>Edit</h1>
  
  <p>I try to go deeper and modify my code a bit:</p>
  
  <pre><code>const q = 'tasks';
  
  const { execSync } = require("child_process");
  const amqplib = require("amqplib");
  
  async function createConnection() {
      console.log("connect");
      const conn = amqplib.connect("amqp://root:toor@0.0.0.0:5672/");
      console.log("connected");
      return conn;
  }
  
  async function createChannel(conn) {
      console.log("create channel");
      const channel = conn.createChannel({durable: false});
      console.log("channel created");
      return channel;
  }
  
  async function createConnectionAndChannel() {
      const conn = await createConnection();
      const channel = await createChannel(conn);
      return channel;
  }
  
  Promise.all([createConnectionAndChannel(), createConnectionAndChannel()])
  
      .then((channels) =&gt; {
  
          // Let's say rabbitmq is down, and then up again
          console.log("restart server");
          execSync("docker stop rabbitmq");
          execSync("docker start rabbitmq");
          console.log("server restarted");
  
          return Promise.all([createConnectionAndChannel(), createConnectionAndChannel()]);
          // return channels;
      })
  
      .then(async (channels) =&gt; {
          console.log("channels created");
          const [publisherChannel, consumerChannel] = channels;
  
          // publisher
          console.log("publish");
          await publisherChannel.assertQueue(q).then(function(ok) {
              console.log("published");
              return publisherChannel.sendToQueue(q, Buffer.from("something to do"));
          });
  
          // consumer
          console.log("consume");
          await consumerChannel.assertQueue(q).then(function(ok) {
              console.log("consumed");
              return consumerChannel.consume(q, function(msg) {
                  if (msg !== null) {
                      console.log(msg.content.toString());
                      consumerChannel.ack(msg);
                  }
              });
          });
  
      })
  
      .catch(console.warn);
  
  </code></pre>
  
  <p>And I get this output:</p>
  
  <pre><code>connect
  connected
  connect
  connected
  create channel
  channel created
  create channel
  channel created
  restart server
  server restarted
  connect
  connected
  connect
  connected
  { Error: Socket closed abruptly during opening handshake
      at Socket.endWhileOpening (/home/guldan/Projects/kata/merapi-plugin-service-rabbit/node_modules/amqplib/lib/connection.js:260:17)                                                                                             
      at Socket.emit (events.js:202:15)
      at endReadableNT (_stream_readable.js:1129:12)
      at processTicksAndRejections (internal/process/next_tick.js:76:17)
    cause:
     Error: Socket closed abruptly during opening handshake
         at Socket.endWhileOpening (/home/guldan/Projects/kata/merapi-plugin-service-rabbit/node_modules/amqplib/lib/connection.js:260:17)                                                                                          
         at Socket.emit (events.js:202:15)
         at endReadableNT (_stream_readable.js:1129:12)
         at processTicksAndRejections (internal/process/next_tick.js:76:17),
    isOperational: true }
  </code></pre>
  
  <p>So I guess amqplib is <strong>able to re-connect</strong> but <strong>fail to create channel</strong>.</p>