2016-11-12 5 views
3

React NativeでWebSocketを使用していて、いくつか問題があります。アプリを更新すると、以前のWebSocket接続(リフレッシュ前に使用されていた)がまだ生きていて、正しく閉じられていないことがわかりました。私がアプリケーションをリロードするたびに、新しい接続が作成されます。それから、私はアプリケーションをシャットダウンし、すべての接続を一緒に解放します。ReloadアプリでWebSocketがクローズされていない(Reactネイティブ)

ブラウザでほぼ同じコードをテストしているときに、ページを更新すると、ソケットが自動的に閉じられ、ページが読み込まれたときに新しいWebsocketが作成されます。

この問題が本番環境で引き続き発生する場合は、非常に重大な問題になる可能性があります。

これは(Iエクスプレス-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 
    }); 
}); 

サーバだけ接続上で受信用WebSocketを保存し、閉じたときにそれを削除します。あなたは、私はそれがこの(使用ノード-UUID)のように見える、それぞれの識別のための接続が便利なのWebSocketてしまったときに私が作ったソケットIDを記録していることがわかります。

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

[OK]を、私は、Webブラウザでこのサーバをテストしたとき、それはうまくいった。すべてのリフレッシュに成功したソケットは閉じられ、新しいものが作成されました。

しかし、React Nativeでは、アプリケーションを更新する際にソケットが決して閉じられませんでした。最後に、いくつか更新され、アプリを終了した後、突然、これらのメッセージは、一度にコンソールに表示された:

コード以下は
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. 

は私がネイティブアプリに反応するのWebSocket扱う部分です。

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); 
} 

アプリを手動で終了する前にソケットを閉じる必要があり、誰でもこれについて知っていれば、助言をお願いします。私はReact Nativeについてあまりよく知らないし、googleに関する関連記事も見つからなかったので、いくつかのアドバイスをお願いします。ありがとう!

P.S.ああ、私はテストのためにAndroidを使いました。

答えて

2

コードがよさそうです。リフレッシュすると、デバッグモードで実行中にJavaScriptがリフレッシュされますか?それは生産では決して起こらないはずです、javascriptはデバイスに保存されています。

あなたはアプリがバックグラウンドで動作しているとき、接続を明示的にクローズする必要がある場合は、チェックアウト:アプリがバックグラウンドで動作しているとき

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

を次にあなたがws.close()を呼び出すことができますが:)

+1

感謝!あなたが言ったように、生産モードとしてビルドした後、それは正常に動作しています。もう一つの有用な情報をありがとう。 :) – modernator

関連する問題