ZeroMQ: Java 请求/响应和发布/订阅模式的简单实现

本文简单的记录了 使用Java实现zmq的请求/响应和发布/订阅模式


POM

	<!-- jeromq -->
    <dependency>
    	<groupId>org.zeromq</groupId>
        <artifactId>jeromq</artifactId>
        <version>0.4.3</version>
   	</dependency>

一、请求响应模式(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);
}

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();
    }

}

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();
    }
}

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();
    }
}

测试结果

在这里插入图片描述

在这里插入图片描述

二、发布/订阅模式(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);
    }
}

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);
}

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);
        }
    }
}

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();
    }
}

测试结果

在这里插入图片描述

在这里插入图片描述


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值