我正在使用 React-Native 创建一个应用程序,并使用 websocket 接收数据。
但是,当我按下主页按钮使我的应用程序在后台运行时,websocket 将暂停,当我再次单击我的应用程序时,websocket 将继续,这完全没问题,但我的问题是我的应用程序是否处于后台模式超过 10分钟,当我再次打开我的应用程序时,websocket 完全停止。我怎么解决这个问题?

我知道我可以使用 Appstate 来检测我的应用程序是否处于后台模式。但我认为这不是我现在真正需要的!

还有另一个类似的问题:

如果用户留在应用程序中但他们的手机自动锁定,当他们再次打开手机时,websocket 也已关闭怎么办。
我怎样才能让 websocket 再次继续?

有任何想法吗?

最佳答案

我们有一个使用 websockets 的应用程序,我们的问题是如果我们的 REST 服务器重启,所有客户端都应该重新打开 web socket。所以我们使用 setInterval 以固定速率 ping 服务器,并在出现错误时重新创建套接字,这是我们的套接字管理器类的代码:

export default class SocketManager {
  constructor(endPoint, handlers) {
    this.endPoint = endPoint;
    this.handlers = handlers;

    this.createSocket();
  }

  createSocket() {
    if (this.interval) clearInterval(this.interval);
    this.socket = this.buildSocket();
    this.pings = 0;
    this.pongs = 0;

    this.interval = setInterval(() => {
      this.socket.send("ping");
      this.pings++;
    }, 3000);
  }

  closeSocket = () => {
    console.log("Cerrando socket");
    if (this.interval) clearInterval(this.interval);
    this.socket.close();
  };

  reconnect = () => {
    this.createSocket();
  };

  buildSocket = () => {
    const sock = new WebSocket(this.endPoint);
    sock.onerror = error => {
      console.log("error", error);
      setTimeout(() => this.reconnect(), 3000);
    };
    sock.onmessage = ({ data }) => {
      if (data === "pong") {
        this.pongs++;
        console.log(`${this.pings} pings, ${this.pongs}  pongs`);
        return;
      }
      const handler = this.handlers[data];
      if (handler) {
        handler();
      }
    };

    return sock;
  };
}

我们从一个 redux Action 创建者调用它,如下所示:
const doLogin = ({ email, password }) => {
  const body = doFormBody({ email, password });
  // // //console.log(`endPoint es ${ENDPOINT}`);

  return dispatch => {
    dispatch({ type: CONECTANDO });

    const url = `${ENDPOINT}/rest/login`;
    fetch(url, {
      headers: {
        Accept: "application/json",
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
      },
      method: "POST",
      body
    })
      .then(response => response.json())
      .then(json => {
        if (json.error) dispatch({ type: LOGIN_ERROR, payload: json.error });
        else {
          dispatch({ type: LOGGED_IN, payload: json });
          const adultosSocket = crearSocket(dispatch, json.id);
          dispatch({ type: ESTABLECE_SOCKET, payload: adultosSocket });
        }
      })
      .catch(err => {
        dispatch({ type: LOGIN_ERROR, payload: err.message });
      });
  };
};

该操作使用此辅助函数来最终创建套接字。在任何时候都只保留一个发送 ping 的套接字实例很重要。
const crearSocket = (dispatch, userId) => {
  const endPoint = `${WS_ENDPOINT}/usuarioConectado?userId=${userId}`;
  const handlers = {
    reload: () => {
      const url = `${ENDPOINT}/rest/adultos/${userId}`;
      fetch(url)
        .then(response => response.json())
        .then(json => dispatch({ type: ADULTOS_CARGADOS, payload: json }))
        .catch(err => dispatch({ type: ADULTOS_ERROR, payload: err.message }));
    }
  };

  return new SocketManager(endPoint, handlers);
};

这不是玩具代码,实际上在我们的应用程序中运行,所以它可以工作。

关于android - 应用程序在后台运行超过 10 分钟后,Websocket 关闭。 ( react native ),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51476104/

10-10 17:11
查看更多