简体   繁体   中英

Javascript - Using Promises on Websocket?

I am using Websockets in pure Javascript and I want to implement Promises into the Websocket functions. I don't get any errors but the Promise doesn't work.

Using the following code I can connect succesful to the socketserver but the Promise seems to be skipped because the output of the alert is always "failed".

Does somebody knows what the problem is in this case? Ps: I did the tests in the latest Google Chrome browser and the latest Mozilla Firefox browser, and I left out some basic checking/error handling for this example.

function Connect()
{
    server = new WebSocket('mysite:1234');

    server.onopen = (function()
    {
        return new Promise(function(resolve, reject) 
        {
            if (true)
            {
                resolve();
            }
            else
            {
                reject();
            }
        });
    }).then = (function()
    {
        alert('succeeed');
    }).catch = (function()
    {
        alert('failed');
    });
}

Your attempt to use promises with the new connection seems a bit misguided. You will want to return a promise from connect() so you can use it to know when the server is connected.

It seems like you probably want something like this:

function connect() {
    return new Promise(function(resolve, reject) {
        var server = new WebSocket('ws://mysite:1234');
        server.onopen = function() {
            resolve(server);
        };
        server.onerror = function(err) {
            reject(err);
        };

    });
}

Then, you would use it like this:

connect().then(function(server) {
    // server is ready here
}).catch(function(err) {
    // error here
});

or with async/await like this:

async myMethod() {
  try {
      let server = await connect()
      // ... use server
  } catch (error) {
      console.log("ooops ", error)
  }
}

I faced exactly the same problem and created tiny websocket-as-promised library. It returns promises for connecting / disconnecting and sending messages:

const WebSocketAsPromised = require('websocket-as-promised');
const wsp = new WebSocketAsPromised();

// connect
wsp.open('ws://echo.websocket.org')
  .then(() => console.log('Connected.')) 
  // send data and expect response message from server
  .then(() => wsp.sendRequest({foo: 'bar'}))
  .then(response => console.log('Response message received', response))
  // disconnect
  .then(() => wsp.close())
  .then(() => console.log('Disconnected.'));

Concerning messages there are two options:

  1. if you send data and expect response message - you can use promise via .sendRequest() method:

     wsp.sendRequest({foo: 'bar'}); // returns promise // actually sends message with unique id: {id: 'xxxxx', foo: 'bar'} // promise waits response message with the same id: {id: 'xxxxx', response: 'ok'} 
  2. if you just want to send message and do not expect response - use .send() method:

     wsp.send(data); // returns undefined 

To extend @jfriend00 answer, as his answer tries to create a new connection every time the connect method is called and it does not consider the case where the connection is closed

function getSocket() {

  if (getSocket.server && getSocket.server.readyState < 2) {
    console.log("reusing the socket connection [state = " + getSocket.server.readyState + "]: " + getSocket.server.url);
    return Promise.resolve(getSocket.server);
  }

  return new Promise(function (resolve, reject) {

    getSocket.server = new WebSocket(SOCKET_URL);

    getSocket.server.onopen = function () {
      console.log("socket connection is opened [state = " + getSocket.server.readyState + "]: " + getSocket.server.url);
      resolve(getSocket.server);
    };

    getSocket.server.onerror = function (err) {
      console.error("socket connection error : ", err);
      reject(err);
    };
  });
}

and to use it

getSocket().then(function(server) {
  // do stuff
}).catch(function(err) {
    // error here
});

or with async/await

const socket = await getSocket();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM