我正在开展一个项目,在这个项目中,我将某些数据包添加到队列中以便稍后处理(下一个600ms的时间段处理队列中的所有数据包)。
但是,我目前遇到的问题是,当在同一个周期内接收到两个数据包时,队列的表现非常奇怪。
在班上我有
private ConcurrentLinkedQueue<RSPacket> logicPackets;
public LogicDecoder() {
super();
logicPackets = new ConcurrentLinkedQueue<RSPacket>();
addDecodeable(new SendWalk());
}
并添加我有的数据包
@Override
public void decode(RSPacket packet, Session session) {
GameServer.get().logger().debug("LogicDecoder decoded " + packet.getId() + " - " + packet.getLength() + " - " + packet.getOffset());
for (RSPacket p : logicPackets) {
if (p.getId() == packet.getId()) {
logicPackets.remove(p);
GameServer.get().logger().debug("Removed packet from queue with id " + packet.getId());
break;
}
}
logicPackets.add(packet);
for (RSPacket p : logicPackets) {
GameServer.get().logger().debug("LogicDecoder containsOnDecode " + p.getId());
}
}
这是调用decode的代码,这是decodeDecodables()方法的重要部分 注意:当我尝试不使用getConvertedPacket()
时,仍会出现同样的问题Decoder d = (Decoder) handler;
P converted = (P) d.getConvertedPacket(packet, session);
if (packet.getId() != PACKET.PING.getId()) {
GameServer.get().logger().debug(packet.getId() + " -> " + converted.getId());
}
if (d.canHandle(converted, session) && d.preDecode(converted, session)) {
d.decode(converted, session);
return true;
}
最后,以下是最终使用队列的方法:
@Override
public void onTick(Session session) {
super.onTick(session);
//GameServer.get().logger().debug("We have " + logicPackets.size() + " logicPackets to process");
for (RSPacket p : logicPackets) {
GameServer.get().logger().debug("pending packet id: " + p.getId());
}
RSPacket packet;
while ((packet = logicPackets.poll()) != null) {
//GameServer.get().logger().debug("LogicDecoder onTick Poll " + PACKET.forId(packet.getId()).name());
if (!preDecode(packet, session) || !decodeDecodeables(packet, session)) {
decodeFail(packet, session);
}
}
}
以下是id为8的数据包和id为59的数据包背靠背发送时的输出。
[17:31:32] -> WorldDecoder recieved packet 8
[17:31:32] -> 8 -> 8
[17:31:32] -> LogicDecoder decoded 8 - 21 - 2
[17:31:32] -> LogicDecoder containsOnDecode 8
[17:31:32] -> WorldDecoder recieved packet 59
[17:31:32] -> 59 -> 59
[17:31:32] -> LogicDecoder decoded 59 - 21 - 12
[17:31:32] -> Removed packet from queue with id 59
[17:31:32] -> LogicDecoder containsOnDecode 59
如您所见,第一遍很好,它将数据包8添加到队列中,然后当数据包59再次调用该函数时,它决定我们之前添加的数据包(数据包8)现在是数据包59和在添加之前删除它。老实说,我不知道这里发生了什么。
答案 0 :(得分:1)
通过更改数据包类来实现Cloneable,我能够解决这个问题:
logicPackets.add(packet);
对此:
logicPackets.add((RSPacket)packet.clone());