我正在使用jersey和jetty开发一个简单的休息服务,它从客户端获取一些请求,并将准备好的请求发送到另一个软件(这不是由我制作)。软件发回一些必须分析的消息并发送回客户端。因此,我开发了一个名为SocketReceiver的新线程,它在请求发送到软件后启动。此类使用辅助类,该类存储与udp套接字的连接(实现为单例)。只要每次只有一个请求,解决方案就可以完美运行。如果发出两个请求(来自两个不同的客户端),则会出现并发问题,并且没有响应通过泽西返回给客户端。
这里是套接字接收器的run方法:
@Override
public void run() {
byte[] message = new byte[9999];
DatagramPacket p = new DatagramPacket(message, message.length);
while (returnedObject == null) {
logger.debug("Waiting for incomming message ...");
try {
onDemandInfoServer.getDataRadioSocket().receive(p);
MessageFrame messageFrame = new MessageFrame(message);
// CHECK Length (2. and 3. byte) and CODE (first byte)
if ((message[1] == 0 && message[2] == 0) || !(message[0] == DC_Constants.D_Code
|| message[0] == DC_Constants.G_Code || message[0] == DC_Constants.P_Code)) {
logger.warn("wrong message!");
continue;
}
int length = messageFrame.getLength();
if (length > message.length) {
logger.warn("wrong message!");
continue;
}
byte[] msg = new byte[length];
System.arraycopy(message, 0, msg, 0, length);
logger.debug(LogHelper.getDataAsString(msg));
if (message[0] == DC_Constants.P_Code) {
msg = messageIsParanet(messageFrame);
}
MessageFrame msgFrame = new MessageFrame(msg);
if (!msgFrame.isAcknowledge()) {
newMessageFromDataradio(msgFrame);
}
} catch (IOException e) {
// error handling
}
}
asyncResponse.resume(returnedObject); // returned objects sets when messages being analyszed
}
以下是泽西休息服务的示例:
@Path("/trips")
public class RequestTripListService extends BaseRestService {
private static final Logger logger = Logger.getLogger(RequestTripListService.class);
@POST
@Compress
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void logonToBlock(TripListRequest tripListRequest, @Suspended final AsyncResponse asyncResponse,
@Context HttpServletRequest request) throws IOException {
// Send message via udp
byte[] logonTelegramm = createLogonTelegramm(sequenceNumber);
getOnDemandInfoServer().sendToDataRadio(logonTelegramm);
// Build a new socket receiver and execute it
JourneyOnDemandInfo info = new JourneyOnDemandInfo(terminal, tripListRequest.getBlockNo(), 0, 0, sequenceNumber);
SocketReceiver<TripListUpdate> socketReceiver = new SocketReceiver<>(asyncResponse,
getOnDemandInfoServer(), getXmlCodec(), info, TripListUpdate.class);
socketReceiver.start();
}
}
感谢您的帮助!