modernator modernator - 20 days ago 9
Android Question

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.

Answer

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 :)

Comments