在Jersey REST Api中使用共享UDP套接字

时间:2015-08-26 09:17:47

标签: rest asynchronous concurrency jersey-2.0

我正在使用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();
}
}
  1. 使用共享udp套接字的正确且线程安全的方法是什么?
  2. 如何解决上述问题?
  3. 感谢您的帮助!

0 个答案:

没有答案