[JAVA] Vérifiez la communication entre Android et le serveur node.js avec des tampons de protocole

environnement

Côté Android

Du côté serveur

Choses à faire

Communiquez avec le serveur en utilisant protobuf-gradle-plugin Vérifiez que vous pouvez sérialiser et désérialiser sur Android et communiquer avec le serveur

[Procédure de génération de classe](http://qiita.com/natsuki_summer/items/987f230ec90d231a623c#%E3%82%AF%E3%83%A9%E3%82%B9%E7%94%9F%E6%88%90 % E6% 89% 8B% E9% A0% 86) etc. sont identiques à l'article précédent, ils sont donc omis.

Android et le nœud seuls devraient fonctionner sans la commande protoc ci-dessus

référence

Presque comme c'est http://qiita.com/trairia/items/45488e9eee197d58ed7d officiel https://github.com/google/protobuf-gradle-plugin

fichier .proto

Le contenu était correct, donc c'est le même qu'avant

search_request.proto



syntax = "proto3";

package test;

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

Ajout de la description des tampons de protocole pour build.gradle du projet Android que vous souhaitez utiliser

build.gradle



buildscript {
    repositories {
        //...
        mavenCentral()
    }
    dependencies {
        //...
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.1'
    }
}

//...

app/build.gradle



apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'

android {
    //réduction
}
//paramètres du plug-in protobuf
protobuf {
    //paramètres de protocole
    protoc {
        artifact = "com.google.protobuf:protoc:3.0.0"
    }
    //Utiliser le plug-in javalite
    plugins {
        lite {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }
    }
    //Lié à la tâche
    generateProtoTasks {
        all().each { task ->
            task.plugins {
                lite {}
            }
        }
    }
}

dependencies {
    //...
    compile 'com.google.protobuf:protobuf-lite:3.0.0'
    compile 'com.squareup.okhttp:okhttp:2.7.5'
}

Ajoutez le fichier .proto à {project} / app / src / main / proto /

app/src/main
 ├proto
 │   └search_request.proto
 └java
    └com/example/testapp
        └MainActivity.java

Faites simplement ce qui précède et la classe SearchRequestOuterClass.SearchRequest sera automatiquement générée dans le package et vous devriez pouvoir y accéder à partir du fichier java de votre projet. Lors de la création d'un objet, il ressemble à ce qui suit

SearchRequestOuterClass.SearchRequest.newBuilder()
                .setQuery("xxxx")
                .setPageNumber(1)
                .setResultPerPage(1)
                .build();

Communication testée avec OKHttp Configurez un serveur local avec node.js et envoyez des données sérialisées, et envoyez également des données sérialisées côté serveur en réponse, et confirmez la communication mutuelle, la sérialisation et la désérialisation

Côté client

La destination de communication est http://127.0.0.1:3000/, mais par exemple, si vous configurez un serveur de nœuds sur un PC local et y accédez avec l'Android réel, vous devez réécrire la partie de "127.0.0.1" et la connecter au même wifi Veuillez en faire une IP accessible obtenue par ifconfig etc. du côté Mac avec

MainActivity.java


public class MainActivity extends AppCompatActivity {
    private String TAG = getClass().getName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new AsyncTask<Void, Void, Void>(){
            @Override
            protected Void doInBackground(Void... params) {
                request();
                return null;
            }
        }.execute();

    }
    //Génération de données appropriée
    public static SearchRequestOuterClass.SearchRequest getData(){
        return SearchRequestOuterClass.SearchRequest.newBuilder()
                .setQuery("huga")
                .setPageNumber(1)
                .setResultPerPage(1)
                .build();
    }

    private void request(){
        postBinary("http://127.0.0.1:3000/", new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.d(TAG, "request --- onFailure:"+e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                Log.d(TAG, "request --- onResponse:"+response);
                SearchRequestOuterClass.SearchRequest data = SearchRequestOuterClass.SearchRequest.parseFrom(response.body().bytes());
                Log.d(TAG, "response --- data.getQuery:"+data.getQuery());
            }
        });
    }

    private void postBinary(String url, final Callback callback){
        OkHttpClient client = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        builder.url(url).post(RequestBody.create(MediaType.parse("application/octet-stream"), getData().toByteArray()));
        Request request = builder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request call, IOException e){
                Log.d(TAG, "onFailure --- e:"+e);
                if(callback != null) callback.onFailure(call, e);
            }

            @Override
            public void onResponse(Response response) throws IOException {

                if(callback != null) callback.onResponse(response);
            }
        });
    }
}

Du côté serveur

server.js



var fs = require('fs')
var protobuf = require('protocol-buffers')
var messages = protobuf(fs.readFileSync('search_request.proto'))
//Génération de messages appropriée
var buf = messages.SearchRequest.encode({
  query: "hoge",
  page_number: 1234
})

require('connect')().use(function(req, res, next) {
	next();
}).use(function(req, res) {
	//Sérialiser les demandes d'Android Java
	var body = [];
	req.on('data', function (data) {
		// body +=data;
		body.push(data);
	});
	req.on('end',function(){
		var buf = Buffer.concat( body );

		try {
			console.log(body);
			console.log(buf);
			var obj = messages.SearchRequest.decode(buf)
			console.log(obj)
		} catch (e) {
			console.log(e)
		}
		res.writeHead(200, {'Content-Type': 'application/octet-stream'});
		//Message de réponse
		res.write(buf, 'binary');
		res.end();
	});
  }).listen(3000);

Démarrez le serveur (il expirera avec Ctl + C, alors exécutez-le du côté iOS au démarrage)

node server.js

Contrairement à quand server.js reçoit d'Objective-C, la désérialisation a échoué sauf si l'octet est écrit pour pousser vers var body = [];. Confirmé qu'il peut également être reçu d'Objective-C avec le code ci-dessus

c'est tout

Recommended Posts

Vérifiez la communication entre Android et le serveur node.js avec des tampons de protocole
[Android] Téléchargement d'images du terminal vers le serveur
Android: Comment gérer "Impossible de déterminer la version Java à partir de '10 .0.1 '"
J'ai essayé de vérifier le fonctionnement du serveur gRPC avec grpcurl
migration du tampon de protocole de 2.x vers 3.x
Arrêter de renvoyer du client au serveur
Exécutez node.js depuis Android Java (traitement)
Connectez-vous au serveur Rails avec iPhone
Mettre à jour MySQL de 5.7 à 8.0 avec Docker
Comment vérifier avant d'envoyer un message au serveur avec Spring Integration
Trouvez Raspberry Pi d'Android avec mDNS
Premiers pas avec Language Server Protocol avec LSP4J