目录
- 通信协议设计
- 代码实现
通信协议设计
对于我们客户端与服务器之间的通信协议我们约定如下:
具体的协议设计: 之后我们传递的参数也是这些
关于 type其实是在描述当前这个请求 、 响应是在调用那个API
约定如下
对于channel ,是tcp链接中的一个逻辑上的链接,一个TCP可以有多个Channel,存在的意义是为了让TCP得到复用, 毕竟一个TCP的链接代价挺大
对于客户端来说, 请求是调用一次以上的核心API告诉服务器,我要调用那个类,并传递过来相应的参数,
对于服务器来说 ,响应是给客户端返回这次调用的结果
代码实现
- 定义响应与请求类
package com.example.demo.Common;import lombok.Data;@Data
public class Request {private int type;private int length;private byte[] payload;// 对于请求来说 ,payload表示请求
}
package com.example.demo.Common;import lombok.Data;
// 这个类表示一个响应, 也是根据自定义应用层协议来的
@Data
public class Response {private int type;private int length;private byte[] payload;// 对于响应来说, payload是内容
}
- 首先我们创建所有类的父类 , 里面包含身份标识与channel身份标识,然后具体每个方法参数通过继承的方式来体现
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;/*
* 对于这个类表示 ,一些公共的参数 ,辅助字段
*/
@Data
public class BasicArguments implements Serializable {// 表示 一次请求 / 响应的身份标识, 可以把请求和响应来对上protected String rid;// 这次通信使用的 channel 的身份标识(TCP 内部的链接)protected String channelId;
}
返回父类
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;/*
* 表示各个远程调用的方法的返回值的公共信息
*/
@Data
public class BasicReturns implements Serializable {// 用来标识唯一的请求和响应protected String rid;// 用来标识一个 channelprotected String channelId;//表示远程调用方法的返回值protected boolean ok;
}
3.根据虚拟主机中的方法,将每个方法所需要传递参数的类定义出来
交换机
package com.example.demo.Common;import com.example.demo.mqServer.core.ExchangeType;
import lombok.Data;import java.io.Serializable;
import java.util.Map;@Data
public class ExchangeDeclareArguments extends BasicArguments implements Serializable {private String exchangeName;private ExchangeType exchangeType;private boolean durable;private boolean autoDelete;private Map<String ,Object> arguments;}
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
@Data
public class ExchangeDeleteArguments extends BasicArguments implements Serializable {private String exchangeName;}
队列
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
@Data
public class QueueBindArguments extends BasicArguments implements Serializable {private String queueName;private String exchangeName;private String bindingKey;
}
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
import java.util.Map;
@Data
public class QueueDeclareArguments extends BasicArguments implements Serializable {private String queueName;private boolean durable;private boolean exclusive;private boolean autoDelete;private Map<String ,Object> arguments;
}
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
@Data
public class QueueDeleteArguments extends BasicArguments implements Serializable {private String queueName;
}
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
@Data
public class QueueUnbindArguments extends BasicArguments implements Serializable {private String queueName;private String exchangeName;}
消息
package com.example.demo.Common;import com.example.demo.mqServer.core.BasicProperties;
import lombok.Data;import java.io.Serializable;
@Data
public class BasicPublishArguments extends BasicArguments implements Serializable {private String exchangeName;private String routingKey;private BasicProperties basicProperties;private byte[] body;}
package com.example.demo.Common;import lombok.Data;import java.io.Serializable;
@Data
public class BasicConsumeArguments extends BasicArguments implements Serializable {private String consumerTag;private String queueName;private boolean autoAck;// 这个类对应的 basicConsume 方法中, 还有一个参数, 是回调函数. (如何来处理消息)// 这个回调函数, 是不能通过网络传输的.// 站在 broker server 这边, 针对消息的处理回调, 其实是统一的. (把消息返回给客户端)// 客户端这边收到消息之后, 再在客户端自己这边执行一个用户自定义的回调就行了.// 此时, 客户端也就不需要把自身的回调告诉给服务器了.// 这个类就不需要 consumer 成员了.
}
订阅消息
package com.example.demo.Common;import com.example.demo.mqServer.core.BasicProperties;
import lombok.Data;import java.io.Serializable;
@Data
public class SubScribeReturns extends BasicReturns implements Serializable {private String consumerTag;private BasicProperties basicProperties;private byte[] body;
}