Android side
Server side
Communicate with server using protobuf-gradle-plugin Check that serialization and deserialization can be done on Android and communication with the server
[Class generation procedure](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. are the same as the previous article, so they are omitted.
Android and node alone should work without the above protoc command
Almost as it is http://qiita.com/trairia/items/45488e9eee197d58ed7d official https://github.com/google/protobuf-gradle-plugin
The content was all right, so it's the same as before
search_request.proto
syntax = "proto3";
package test;
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
Add the description for Protocol Buffers to build.gradle of the Android project you want to use
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 {
//abridgement
}
//protobuf plugin settings
protobuf {
//protoc settings
protoc {
artifact = "com.google.protobuf:protoc:3.0.0"
}
//Use javalite plugin
plugins {
lite {
artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
}
}
//Task related
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'
}
Add .proto file to {project} / app / src / main / proto /
app/src/main
├proto
│ └search_request.proto
└java
└com/example/testapp
└MainActivity.java
Just do the above and the SearchRequestOuterClass.SearchRequest class will be automatically generated in the package and you should be able to access it from the java file of your project. When creating an object, it looks like the following
SearchRequestOuterClass.SearchRequest.newBuilder()
.setQuery("xxxx")
.setPageNumber(1)
.setResultPerPage(1)
.build();
Communication tested with OKHttp Set up a local server with node.js and send serialized data, and also send serialized data on the server side in response, and confirm mutual communication, serialization, and deserialization
The communication destination is http://127.0.0.1:3000/, but for example, if you set up a node server on your local PC and access it on the actual Android, you need to rewrite the part of "127.0.0.1" and connect it to the same wifi. Please make it an accessible IP obtained by ifconfig etc. on the Mac side with
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();
}
//Appropriate data generation
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);
}
});
}
}
server.js
var fs = require('fs')
var protobuf = require('protocol-buffers')
var messages = protobuf(fs.readFileSync('search_request.proto'))
//Appropriate message generation
var buf = messages.SearchRequest.encode({
query: "hoge",
page_number: 1234
})
require('connect')().use(function(req, res, next) {
next();
}).use(function(req, res) {
//Serialize request from 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'});
//Response message
res.write(buf, 'binary');
res.end();
});
}).listen(3000);
Start the server (it will expire with Ctl + C, so run it on the iOS side while starting)
node server.js
Unlike when server.js receives from Objective-C, deserialization failed unless byte is written to push to var body = [] ;. Confirmed that it can also be received from Objective-C with the above code
that's all
Recommended Posts