Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSocket not closed on reload app(React Native)

I'm using WebSocket with React Native and have some issues on it. When I refresh the app, I found that previous WebSocket connection(used before refresh) was still alive, and not closed properly. Every time I was reloaded the App, it makes new connection. Then I shutdown the app, it releases all connections together.

When I'm testing almost same code with browser, when I refresh the page, socket is closed automatically and create new Websocket on page loads.

If this problem is still existing on production environment, it could be very critical.

This is server side code(I used express-ws):

const sockets = {};

app.ws('/', (socket, req) => {
    // Generate unique id to socket and save to socket list
    const uid = uuid.v4();
    socket.uid = uid;

    console.log(`Socket ${uid} connected.`);
    sockets[uid] = socket;

    socket.on('message', (data) => {
        broadcast(data);
    });
    socket.on('close', () => {
        console.log(`Socket ${uid} disconnected.`);
        delete sockets[uid];

        broadcast({
            type: 'plain',
            message: `User ${socket.username} leaved the channel.`
        });
        socket = null;  // make sure to remove socket
    });
});

Server just saves received WebSocket on connected, and remove it when closed. You can see that I logged Socket id that I made when got connection for identify each websocket handy, it looks like this(used node-uuid):

Socket d0b62d3a-2ed9-4258-9d2d-e83a3eb99e6c disconnected.

Ok, when I tested this server with Web browsers, it worked well. Every refresh successfully were closed socket and created new one.

But with React Native, socket never closed on refresh the app. After several refreshes, and finally exit the app, suddenly these messages were appear on the console at once:

Socket d0b62d3a-2ed9-4258-9d2d-e83a3eb99e6c disconnected.
Socket 2e1a2bba-ac64-4368-aeca-a02721f28ce5 disconnected.
Socket 6673c9a3-9667-425a-8923-efbc40196226 disconnected.
Socket 08fee145-e9bf-4af0-a245-dda2fe6a8e56 disconnected.
Socket 55ce1926-d7fa-488b-92d9-ff3dea874496 disconnected.
Socket 9c4c166d-d6d6-4a11-b400-a3eac51ab91f disconnected.
Socket 9f6db512-649c-440e-8b88-9a77d20e1943 disconnected.
Socket a9e6c0bd-419c-40af-865a-2573eca26a0f disconnected.
Socket 70835c7a-3230-4e20-b133-b6c2942dff22 disconnected.
Socket 5c83d81c-c0f1-4b9a-b5fb-7f09430a2f09 disconnected.
Socket 4f11aea4-d0ad-4e2b-9613-9e994657ecaf disconnected.

Below code is WebSocket handling part of my React Native app.

import store from './store';
import * as ChatActions from './actions/Chat';
import * as NetworkActions from './actions/Network';

const socket = null;

export function init() {
    socket = new WebSocket('ws://mywebsite.com:3300');

    socket.onopen = () => {
        store.dispatch({
            type: NetworkActions.NETWORK_SOCK_CONNECTED,
            data: {}
        });
    };

    socket.onmessage = (e) => {
        var data = e.data;
        try {
            data = JSON.parse(e.data);
        }
        catch(err) {}

        store.dispatch({
            type: ChatActions.CHAT_RECV,
            data: data.message
        });
    };

    socket.onclose = (e) => {
        store.dispatch({
            type: NetworkActions.NETWORK_SOCK_CLOSED,
            data: {}
        });
    };
}

export function send(data) {
    data = typeof data === 'object' ? JSON.stringify(data) : data;
    socket.send(data);
}

If I should close socket before app ends manually, and anyone know about this, please gimme some advice. I'm not much know about React Native, and not found related posts on google, so it will be very appreciate it gimme some advice. Thanks!

P.S. Oh, and I used Android for testing.

like image 997
modernator Avatar asked Nov 12 '16 08:11

modernator


People also ask

What happens when I use WebSocket in my react native app?

Now if used WebSocket from react-native, app when going in background mode can't to complete task for a certain number of time and system terminated app and innner state reset I expect when i use websocket in my app after hide app websoket finish tasks and app move to suspend mode and inner state not reset

How do I connect to a socket in react?

To facilitate socket communications in React, you'll use the de-facto library socket.io-client. Use the command npm install -S socket.io-client to install it. There are multiple ways of adding WebSocket support to a React app.

What is logrocket in React Native?

LogRocket: Instantly recreate issues in your React Native apps. LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.

How do I use WebSocket in a real world application?

The WebSocket context can be accessed anywhere in the app using the useContext Hook, and all the included functionality will be available. Additionally, a real-world app would also need to handle the instances of socket disconnecting and reconnecting, and handling client exit.


1 Answers

Your code looks good. By refresh do you mean refreshing the javascript while running in debug mode? That should never happen in production, the javascript is stored on the device.

If you need to explicitly close the connection when the app is in the background, check out:

http://facebook.github.io/react-native/docs/appstate.html

Then you can call ws.close() when the app is in the background :)

like image 89
Tucker Connelly Avatar answered Oct 19 '22 06:10

Tucker Connelly