ZeroMQ: Java 请求/响应和发布/订阅模式的简单实现
转载于:https://blog.csdn.net/weixin_47951400/article/details/119142454
POM
<!-- jeromq -->
<dependency>
<groupId>org.zeromq</groupId>
<artifactId>jeromq</artifactId>
<version>0.4.3</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
一、请求响应模式(ZMQ_REQ + ZMQ_REP)
1.REP
package com.example.zmq.repreq;
import org.zeromq.ZMQ;
public abstract class ZmqRepThread implements Runnable {
/**
* ZMQ启动线程数
*/
private int ZMQThreadCount = 1;
/**
* ZMQ数据端口
*/
private int ZMQRepPort;
/**
* ZMQ监听接收端ip
*/
private String ZMQRepIP;
private ZMQ.Context context = null;
private ZMQ.Socket repSock = null;
public ZmqRepThread(String ZMQRepIP, int ZMQRepPort){
this.ZMQRepIP = ZMQRepIP;
this.ZMQRepPort = ZMQRepPort;
initZMQ();
}
/**
* 初始化ZMQ对象
*/
private void initZMQ() {
if (context == null) {
context = ZMQ.context(ZMQThreadCount);
}
if (ZMQRepPort != 0) {
repSock = context.socket(ZMQ.REP);
String bindUri = "tcp://" +ZMQRepIP + ":" + ZMQRepPort;
repSock.bind(bindUri);
} else {
throw new RuntimeException("Error!");
}
}
@Override
public void run() {
while (true) {
try {
byte[] recvBuf = repSock.recv();
if (recvBuf == null) {
continue;
}
if (new String(recvBuf).equals("END")){
break;
}
dealWith(recvBuf,repSock);
} catch (Exception e) {
e.printStackTrace();
}
}
//关闭
repSock.close();
context.term();
}
/**
* 处理接收到数据的抽象方法
*/
public abstract void dealWith(byte[] data,ZMQ.Socket socket);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
2.REQ
import org.zeromq.ZMQ;
public class ZmqReqClient {
/**
* ZMQ启动线程数
*/
private int ZMQThreadCount = 1;
/**
* ZMQ数据广播端口
*/
private int ZMQReqPort;
private String ZMQReqIP;
private ZMQ.Context context = null;
private ZMQ.Socket pubSock = null;
public ZmqReqClient(String ZMQReqIP, int ZMQReqPort) {
this.ZMQReqIP = ZMQReqIP;
this.ZMQReqPort = ZMQReqPort;
if (pubSock == null) {
initZMQ();
}
}
/**
* 初始化ZMQ对象
*/
private void initZMQ() {
if (context == null) {
context = ZMQ.context(ZMQThreadCount);
}
if (context == null) {
context = ZMQ.context(ZMQThreadCount);
}
if (ZMQReqPort != 0) {
pubSock = context.socket(ZMQ.REQ);
String connectUri = "tcp://" + ZMQReqIP + ":" + ZMQReqPort;
pubSock.connect(connectUri);
} else {
throw new RuntimeException("Error!");
}
}
public void sendEND() {
//发送结束信息
pubSock.send("END".getBytes());
//关闭
pubSock.close();
context.term();
}
public byte[] sendData(byte[] msg) {
pubSock.send(msg);
byte[] recv = pubSock.recv();
return recv;
}
public void send(byte[] msg) {
pubSock.send(msg);
byte[] recv = pubSock.recv();
System.out.println(recv);
//发送结束信息
pubSock.send("END".getBytes());
//关闭
pubSock.close();
context.term();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
3.测试
REP
public class Rep {
public static void main(String[] args) {
ZmqRepThread zmqRepThread = new ZmqRepThread("*", 8888) {
@Override
public void dealWith(byte[] data, ZMQ.Socket socket) {
System.out.println("Ressponse recv:\t" + new String(data));
String response = "I got it:\t" + new String(data);
socket.send(response.getBytes());
}
};
Thread thread = new Thread(zmqRepThread);
thread.start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
REQ
public class Req {
public static void main(String[] args) throws InterruptedException {
ZmqReqClient zmqReqClient = new ZmqReqClient("127.0.0.1",8888);
for (int i = 0; i < 100; i++) {
String request = "hello time is " + System.currentTimeMillis();
byte[] recvData = zmqReqClient.sendData(request.getBytes());
System.out.println(new String(recvData));
Thread.sleep(1000);
}
zmqReqClient.sendEND();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
测试结果
二、发布/订阅模式(ZMQ_PUB + ZMQ_SUB)
1.PUB
import org.zeromq.ZMQ;
public class ZmqPubClient {
/**
* ZMQ启动线程数
*/
private int ZMQThreadCount = 1 ;
/**
* ZMQ数据广播端口
*/
private int ZMQSendPort;
private String ZMQPubIP;
private ZMQ.Context context;
private static ZMQ.Socket pubSock;
public ZmqPubClient(String ZMQPubIP, int ZMQPubPort) {
this.ZMQPubIP = ZMQPubIP;
this.ZMQSendPort = ZMQPubPort;
if (pubSock == null) {
initZMQ();
}
}
/**
* 初始化ZMQ对象
*/
private void initZMQ() {
if (ZMQPubIP == null || "".equals(ZMQPubIP)) {
throw new RuntimeException("IP Error!");
}
if (context == null) {
context = ZMQ.context(ZMQThreadCount);
}
if (ZMQSendPort != 0) {
pubSock = context.socket(ZMQ.PUB);
String bindUri = "tcp://" +ZMQPubIP + ":" + ZMQSendPort;
pubSock.bind(bindUri);
pubSock.send("");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
throw new RuntimeException("Error!");
}
}
public void sendData(byte[] msg) {
pubSock.send(msg, ZMQ.NOBLOCK);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
2. SUB
import org.zeromq.ZMQ;
/**
* ZMQ接收线程
*/
public abstract class ZmqSubThread implements Runnable {
/**
* ZMQ启动线程数
*/
private int ZMQThreadCount = Integer.parseInt("1");
/**
* ZMQ接收端口
*/
private int ZMQRecvPort;
/**
* ZMQ监听接收ip
*/
private String ZMQRecvIP;
private ZMQ.Context context = null;
private ZMQ.Socket subSock = null;
public ZmqSubThread() {
initZMQ();
}
public ZmqSubThread(String ZMQRecvIP, int ZMQRecvPort) {
this.ZMQRecvIP = ZMQRecvIP;
this.ZMQRecvPort = ZMQRecvPort;
initZMQ();
}
/**
* 初始化ZMQ对象
*/
public void initZMQ() {
if (ZMQRecvIP == null || "".equals(ZMQRecvIP)) {
throw new RuntimeException("IP Error!");
}
if (ZMQRecvPort == 0) {
throw new RuntimeException("Port Error!");
}
context = ZMQ.context(ZMQThreadCount);
subSock = context.socket(ZMQ.SUB);
String ConUri = "tcp://" + ZMQRecvIP + ":" + ZMQRecvPort;
subSock.connect(ConUri);
subSock.subscribe("".getBytes());
}
@Override
public void run() {
while (true) {
try {
byte[] recvBuf = subSock.recv(ZMQ.SUB);
if (recvBuf == null) {
continue;
}
dealWith(recvBuf);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 处理接收到数据的抽象方法
*/
public abstract void dealWith(byte[] data);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
3.测试
PUB
public class Pub {
public static void main(String[] args) throws InterruptedException {
ZmqPubClient zmqPubClient = new ZmqPubClient("127.0.0.1",7777);
for (int i = 0; i < 1000;i++){
String data = "data:\t" + System.currentTimeMillis() + "\t" + i;
zmqPubClient.sendData(data.getBytes());
System.out.println(data);
Thread.sleep(1000);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
SUB
public class Sub {
public static void main(String[] args) {
ZmqSubThread zmqSubThread = new ZmqSubThread("127.0.0.1",7777) {
@Override
public void dealWith(byte[] data) {
System.out.println(new String(data));
}
};
Thread thread = new Thread(zmqSubThread);
thread.start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12