33
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MessagePack-RPCでJavaとPythonで連携してみる

Last updated at Posted at 2016-01-07

前書き

JavaとPythonで作ったシステムを統合したい,Javaで実装したシステムをPythonスクリプトで気軽に操作できるようにしたい,という必要に迫られて実験.
最初は自分で適当にプロトコル決めるかなーとか思っていたけど,MessagePack-RPCがとっても便利そうだったのでのっかることに.

やってみたこと

要は,Java側のメソッドをPythonから呼ぶ,Python側のメソッドをJavaから呼ぶというのがしたいこと.もちろん,引数や返り値も扱えないといけない.
というわけで,今回は,

  • 文字列を渡してとHelloつきの文字を返してもらう(hello)
  • 2つの引数を渡して足した値を返してもらう(add)
  • 数の配列を渡して合計値を返してもらう(sum)
  • 数の配列を渡して,matplotlibで作った折れ線グラフイメージを返してもらう(make_graph)

というのをやってみます.サーバー側がPython,クライアント側がJavaです.

コード

Python側のコード

server.py
import msgpackrpc
import matplotlib.pyplot as plt
from PIL import Image

class TestServer(object):

    def hello(self, mesg):
        print(mesg)
        return ("Hello, " + mesg.decode()).encode()

    def add(self, a, b):
        return a + b

    def sum(self, d):
        return sum(d)

    def make_graph(self, d):
        plt.plot(d)
        plt.savefig('hoge.png')
        f = open('hoge.png', 'rb')
        d = f.read()
        f.close()
        return d

server = msgpackrpc.Server(TestServer())
server.listen(msgpackrpc.Address("localhost", 1985))
server.start()

Java側のコード

TestClient.java
import org.msgpack.rpc.Client;
import org.msgpack.rpc.loop.EventLoop;
import org.msgpack.type.Value;

import java.io.*;
import java.util.*;
import java.awt.image.*;
import javax.swing.*;
import javax.imageio.*;

public class TestClient {

    public static void main(String[] args) throws Exception {

        EventLoop loop = EventLoop.defaultEventLoop();
        Client client = new Client("localhost", 1985, loop);
                int v;

        System.out.println(" --- hello ---");
        Value result = client.callApply("hello", new Object[]{"miyo"});
        System.out.println("Result type:" + result.getType());
        String s = new String(result.asRawValue().getByteArray());
        System.out.println(s); // Hello, miyo
        System.out.println();

        System.out.println(" --- add --- ");
        result = client.callApply("add", new Object[]{100, 10}); // 110
        System.out.println("Result type:" + result.getType());
        v = result.asIntegerValue().getInt();
        System.out.println("result = " + v + " :" + (v == 110));
        System.out.println();

        System.out.println(" --- sum --- ");
        result = client.callApply("sum", new Object[]{new int[]{1, 2, 3, 4, 5}}); // 15
        System.out.println("Result type:" + result.getType());
        v = result.asIntegerValue().getInt();
        System.out.println("result = " + v + " :" + (v == 15));
        System.out.println();

        System.out.println(" --- make graph ---");
        result = client.callApply("make_graph",
                                  new Object[]{new int[]{1,2,4,8,10,3,6,8,9,-1}});
        System.out.println("Result type: " + result.getType());
        byte[] raw = result.asRawValue().getByteArray();
        BufferedImage img = ImageIO.read(new ByteArrayInputStream(raw));
        System.out.println(img);
        Icon icon = new ImageIcon(img);
        JOptionPane.showMessageDialog(null,
                                      "",
                                      "image",
                                      JOptionPane.PLAIN_MESSAGE,
                                      icon);
        client.close();
        loop.shutdown();
    }
}

実行結果

実行したターミナルの様子はこんな感じ
result_console.PNG

Pythonで生成したグラフもちゃんと表示できた
result_graph.PNG

いやー,便利だわ!!

参考

いろいろ参考にしすぎてメモしそこねた...

33
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?