長い接続する2つの通信システムを実現するNSDサービス&網状(再接続、ハートビート、スティッキーパケット処理)によってアンドロイドは、Androidを終了します

####はじめに

(着信番号通知機能を含む)の携帯電話番号のAppエンドマシンを取ることによって最近の需要、現在の数に召喚選手の数のための別のAndroidの広告に、リアルタイムの接続。

2台のAndroidのマシンがあります。

「アンドロイドのサンミベースのバージョンは、小さな券売機することができます。」

「大画面テレビでのAndroidのシステム接続箱。」

短いDOに接続する2台のマシンが互いに通信で、ステーションは、データ処理表示を送信します。最終的には両端で交換て実現!
直接使用することに献身を終えデモプロジェクトに基づいています。

IMG20180601171657.jpg

本篇ディレクトリ

###通信の適切な手段を見つける1
2.NSDの###役割と意義
### 3 NSDさんの発展の過程について
の### 4.NSD Serverのサーバーサイド開発
5.NSDクライアントの顧客を###開発側で
### 6.Nettyサーバー側の開発

7.Nettyクライアントの開発

8.元アドレスのアイデア

説明する時間がない、速い車
、速いクルマを説明する時間がないが

###通信の適切な手段を見つける1.
MQまたはソケットを使用して?
MQ間とソケットの下の違いを学ぶのか?Baiduの何かネットワーキングプロダクトマネージャーから引用し、次の文:

「TCPベースのパブ/サブプロトコルの物事のシーンデザインのMQTT順序は、そのようなので、上の異なるネットワークQoS、レベルをテーマに、最後の言葉、とに適応するように最適化機能のための多くのものが、あります。
サーバとの双方向通信を容易にするためのWebSocket HTML5アプリケーションMQTTとしてどのようにHTML5アプリケーション:などの古い実装するサーバープッシュ、彗星、ロングポーリングを、交換する前に、プロトコルの設計、HTTPプロトコルのTCPハンドシェイクは、理由のシナリオ、全て2の交点を持って使用左折しますメッセージを受信したり、デバイスに情報を送信、自然になるため、その後MQTT以上のWebSocket最も合理的な方法にするクライアントデバイス。」

MQTTは、通信の一部を達成するために、安定性を、物事の間の通信に適して考えるようになったし、長いバック接続とみなさので。ソケットに対処することを決定し、ソケットは便利な車輪を見つけることを検討してください。オープンソースの安定を使用し、「ベースネッティー

ベースネッティーは同じでAndroidの「へのアプリケーションに適用され見に行ってきましたNettyDemo」このデモは私がしたいことが非常に望ましいとして記述することができ、クライアント、モバイル端末(再接続、ハートビート、粘着性のパケット処理)が含まれています。

あなたは、サーバーのアドレスを知っている必要があり、IP経由で事前にサーバーとのソケットによってポートに接続する必要があります。ユーザが手動であまりに面倒な入力することができ、接続及び通信の両端を確実にするために。Androidの後にNSDサービスで見つかった、サーバがそれを介してNSDによって事前に登録されたアドレスを発見することがあります。本当に素晴らしいです。

アンドロイドNSDサービスはコメント
NSDフルネーム:ネットワークサービスの発見は意味翻訳ネットワークサーバの意味を見つけることです。理解するために、このです:対応のInternet Information Serverを見つけます。

###役割と2.NSDの意義

ネットワークに直接接続されていないNSDだけ見つかったネットワークは、ネットワークの発見は、LANの発見は、ネットワークに接続されてもよいし、対応するデバイスのIPアドレスとポート番号を取得します。

NSDの役割は、同じローカルエリアネットワーク接続ソケット2台の電話機とのデータ通信を使用するなど、次の接続のためのネットワークの準備ができようにすることです、サーバーのIPアドレスとポート番号を知る必要があります。

#### 3. NSDの発展の過程について。
NSD(NsdManager)がAndroidのSDKに付属しているクラスライブラリで、あなたは直接プログラムを呼び出すことができます。
ヒント:使用NSDサービスminSdkVersionが> 16

実際には、ある程度類似NSDとソケット、サーバ側とクライアントサーバークライアントがあります

ソケットの場合:

サーバのポート番号を定義し、接続をリッスンするSocketServerの必要性
サーバーのポート番号とサーバの定義を知るために、IPアドレスSocketClientクライアントのニーズ、その後、接続を要求
し、クライアント側に接続するための要求を送信し、サーバ側の接続同意し、ソケット接続それが設定されている、彼らはお互いを上にして通信することができます。

NSDの場合:

NSDサーバーのサーバー定義されたホスト名、ポート番号、その後、登録NSD
NSDクライアントクライアントのスキャンが、ホスト名にのみスキャンNSD Serverサーバーで定義されたオブジェクトにNsdServiceInfoが含まれていることができ
、その後NSDクライアントクライアントは、このNsdServiceInfoに従ってオブジェクトを解決することができますサーバーIPアドレスとポート番号

事実:NSDは準備へのソケット接続手段の一つです!

### 4.NSDサーバーサイド開発サービスは、
NSDはサーバのアドレスに検索することができる登録しました。本明細書で使用する場合、パッケージは名前とポート番号を指定する必要がありました

    /**
     * 服务器端注册一个可供NSD探测到的网络 Ip 地址,便于给展示叫号机连接此socket
     */
    Runnable nsdServerRunnable = new Runnable() {
        @Override
        public void run() {

            NSDServer nsdServer = new NSDServer();
            nsdServer.startNSDServer(MainActivity.this, NSD_SERVER_NAME, NSD_PORT);

            nsdServer.setRegisterState(new NSDServer.IRegisterState() {
                @Override
                public void onServiceRegistered(NsdServiceInfo serviceInfo) {
                    Log.i(TAG, "已注册服务onServiceRegistered: " + serviceInfo.toString());
                    //已经注册可停止该服务
//                    nsdServer.stopNSDServer();
                }
                @Override
                public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

                }
                @Override
                public void onServiceUnregistered(NsdServiceInfo serviceInfo) {

                }
                @Override
                public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

                }
            });
        }
    };

    private void registerNsdServer() {

        new Thread(nsdServerRunnable).start();
    }

### 5.NSDクライアント開発クライアント
サーバー名を指定してNSDClientパッケージタイプの検索に登録は、IPとポートが解決取得するコールバック。その後、ネッティーソケットに接続することができます。


    /**
     * 通過 Nsd 搜索註冊過的服務端名称 解析后拿到 IP 和端口 ,進行 NettySocket 的連接
     */
    private void searchNsdServer() {

        nsdClient = new NsdClient(MainActivity.this, SERVER_NAME, new NsdClient.IServerFound() {
            @Override
            public void onServerFound(NsdServiceInfo info, int port) {
                if (info != null) {
                    String hostAddress = info.getHost().getHostAddress();

                    tvConnect.setText("NSD查询到指定服务器信息:\n" + info.toString());

                    //获取到指定的地址,进行Netty的连接
                    connectNettyServer(hostAddress, port);

                    if (info.getServiceName().equals(SERVER_NAME)) {
                        //掃描到對應後過後停止Nsd掃描
                        nsdClient.stopNSDServer();
                    }
                }
            }

            @Override
            public void onServerFail() {

            }
        });

        nsdClient.startNSDClient();
    }

開発6.Nettyサーバ側###
オープンソケットサービスは、クライアント接続を待って、スレッドを開く必要があります

  
   //  开启Socket 服务需要开启一个线程处理,等待客户端连接
 
    private void initNetty() {

        if (!EchoServer.getInstance().isServerStart()) {
            new NettyThread().start();
        }

    }


    class NettyThread extends Thread {
        @Override
        public void run() {
            super.run();

            EchoServer.getInstance().setListener(new NettyListener() {
                @Override
                public void onMessageResponse(Object msg) {

                    Log.i(TAG, "Server received: " + (String) msg);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            tvContent.setText("Server received: " + msg);

                            Toast.makeText(MainActivity.this, String.valueOf(msg), LENGTH_SHORT).show();
                        }
                    });

                }

                @Override
                public void onChannel(Channel channel) {
                    //设置通道连接到封装的类中
                    EchoServer.getInstance().setChannel(channel);

                    Log.i(TAG, "建立连接 onChannel(): " + "接收(" + channel.toString() + ")");

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvNetty.setText("接收:(" + channel.toString() + ")");

                        }
                    });
                }

                @Override
                public void onStartServer() {
                    Log.i(TAG, "Netty Server started 已开启");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "Netty Server 已開啟", LENGTH_SHORT).show();
                        }
                    });

                }

                @Override
                public void onStopServer() {
                    Log.i(TAG, "Netty Server started 已开启");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "Netty Server 未連接", LENGTH_SHORT).show();

                        }
                    });
                }

                @Override
                public void onServiceStatusConnectChanged(int statusCode) {

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
                                Log.i(TAG, "STATUS_CONNECT_SUCCESS:");
                                //标记连接的状态
                                vOpenAppGetCode.setSelected(true);
                            } else {
                                Log.i(TAG, "onServiceStatusConnectChanged:" + statusCode);
                                tvNetty.setText("接收:");
                                vOpenAppGetCode.setSelected(false);

                            }
                        }
                    });
                }
            });
            //入口 开启Netty Server
            EchoServer.getInstance().start();
        }
    }


7.Nettyクライアントの開発

NSDによると接続するためのサーバーのIPとポートを指定するには、検索します。

    /**
     * 连接Netty 服务端
     *
     * @param host 服务端地址
     * @param port 服务端端口 默认两端约定一致
     */
    private void connectNettyServer(String host, int port) {

        mNettyClient = new NettyClient(host, port);

        Log.i(TAG, "connectNettyServer");
        if (!mNettyClient.getConnectStatus()) {
            mNettyClient.setListener(new NettyListener() {
                @Override
                public void onMessageResponse(Object msg) {
                    Log.i(TAG, "onMessageResponse:" + msg);
                    /**
                     *   接收服务端发送过来的 json数据解析
                     */
                    // TODO: 2018/6/1  do something
                    // QueueShowBean    queueShowBean = JSONObject.parseObject((String) msg, QueueShowBean.class);

                    //需要在主线程中刷新
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            Toast.makeText(MainActivity.this, msg + "", Toast.LENGTH_SHORT).show();

                            tvNetty.setText("Client received:" + msg);
                        }
                    });


                }

                @Override
                public void onServiceStatusConnectChanged(int statusCode) {
                    /**
                     * 回调执行还在子线程中
                     */
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
                                Log.e(TAG, "STATUS_CONNECT_SUCCESS:");
                                vNettyStatus.setSelected(true);
                            } else {
                                Log.e(TAG, "onServiceStatusConnectChanged:" + statusCode);
                                vNettyStatus.setSelected(false);
                            }
                        }
                    });
                }
            });

            mNettyClient.connect();//连接服务器
        }
    }

シーンコードは、上記フラグメントの使用を介してカプセル化されます。

8.元アドレスのアイデア

参考プロジェクト:
包装カテゴリNSD参照アンドロイドNSDサービスは、詳細な彼はすべてのアドレスを検索することです。そして、これは指定されたフィルタではありません。アカウントに指定された対応する接続を取ると、それがプロジェクトの名前によってフィルタリングされなければならないために変更されました。

ネッティーは「からのすべてのキー参照を使用GitHubのNettyDemo
このNettyDemo素晴らしいと非常にコンパクトなパッケージを。達成の設定(再接続、心拍数、パケット処理スティッキー)

このプロジェクトは、アドレスのGithubを

ヒント:
特別な注意ネッティーチャネルコールバックチャネルは操作がメインラインで実行する必要があるUIを更新する非同期スレッドで更新されるが、そうでなければ、切断と再接続にこのチャンネルであったであろう。今朝これを書くためのデモの時間がピットを強化している、コードはまったく同じです、ただ受信した値を設定するために直接サービス側onMessageResponse()メソッドでビューを呼び出し、直接にリンクされ、チャンネルが再接続されています。主に私自身が問題ありませんプロジェクトへのコードの行に気付きませんでした。本当にあなたは、低レベルのフラッシュブラインドブラインド僧の一握りを練習する必要があります- -

1527840976822.jpg

公開された26元の記事 ウォン称賛19 ビュー40000 +

おすすめ

転載: blog.csdn.net/a23006239/article/details/80540175