プロジェクトで TCP 経由で PGM を使用する利点をテストするために、Java フレーバーの zmq を試しています。そこで、天気の例を zmq ガイドから、epgm トランスポートを使用するように変更しました。すべてがコンパイルされて実行されますが、何も送受信されていません。トランスポートを TCP に戻すと、サーバーはクライアントから送信されたメッセージを受信し、期待どおりのコンソール出力が得られます。
では、PGM を使用するための要件は何ですか? bind メソッドと connect メソッドに渡す文字列を変更し、zmq_pgm の zmq API に従っています: "transport://interface;multicast address:port"。それはうまくいきませんでした。この形式を使用しようとすると、無効な引数エラーが発生します。そのため、「機能する」インターフェイスとセミコロンを削除して単純化しましたが、結果が得られません。
pgm/epgm を使用する jzmq の例を見つけることができず、Java バインディングの API ドキュメントでは、バインドまたは接続に渡されるエンドポイントの適切な文字列形式が定義されていません。それで、私はここで何が欠けていますか?クライアントとサーバーに異なるホストを使用する必要がありますか?
注目すべき点の 1 つは、VirtualBox VM (Ubuntu 14.04/OSX Mavericks ホスト) でコードを実行していることです。それが私が現在直面している問題と関係があるかどうかはわかりません。
サーバ:
public class wuserver {
public static void main (String[] args) throws Exception {
// Prepare our context and publisher
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("epgm://xx.x.x.xx:5556");
publisher.bind("ipc://weather");
// Initialize random number generator
Random srandom = new Random(System.currentTimeMillis());
while (!Thread.currentThread ().isInterrupted ()) {
// Get values that will fool the boss
int zipcode, temperature, relhumidity;
zipcode = 10000 + srandom.nextInt(10000) ;
temperature = srandom.nextInt(215) - 80 + 1;
relhumidity = srandom.nextInt(50) + 10 + 1;
// Send message to all subscribers
String update = String.format("%05d %d %d", zipcode, temperature, relhumidity);
publisher.send(update, 0);
}
publisher.close ();
context.term ();
}
}
クライアント:
public class wuclient {
public static void main (String[] args) {
ZMQ.Context context = ZMQ.context(1);
// Socket to talk to server
System.out.println("Collecting updates from weather server");
ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
//subscriber.connect("tcp://localhost:5556");
subscriber.connect("epgm://xx.x.x.xx:5556");
// Subscribe to zipcode, default is NYC, 10001
String filter = (args.length > 0) ? args[0] : "10001 ";
subscriber.subscribe(filter.getBytes());
// Process 100 updates
int update_nbr;
long total_temp = 0;
for (update_nbr = 0; update_nbr < 100; update_nbr++) {
// Use trim to remove the tailing '0' character
String string = subscriber.recvStr(0).trim();
StringTokenizer sscanf = new StringTokenizer(string, " ");
int zipcode = Integer.valueOf(sscanf.nextToken());
int temperature = Integer.valueOf(sscanf.nextToken());
int relhumidity = Integer.valueOf(sscanf.nextToken());
total_temp += temperature;
}
System.out.println("Average temperature for zipcode '"
+ filter + "' was " + (int) (total_temp / update_nbr));
subscriber.close();
context.term();
}
}