TcpSynchronousWaitingRoom.java 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package wei.yigulu.modbus.domain.synchronouswaitingroom;
  2. import lombok.extern.slf4j.Slf4j;
  3. import wei.yigulu.modbus.domain.datatype.numeric.P_AB;
  4. import java.nio.ByteBuffer;
  5. import java.util.Map;
  6. import java.util.concurrent.ConcurrentHashMap;
  7. /**
  8. * 同步等待室 将请求和响应同步起来
  9. *
  10. * @author: xiuwei
  11. * @version:
  12. */
  13. @Slf4j
  14. public class TcpSynchronousWaitingRoom implements SynchronousWaitingRoom {
  15. public static long waitTime = 2000L;
  16. protected Map<Integer, Guest> guestMap = new ConcurrentHashMap<>();
  17. @Override
  18. public ByteBuffer getData(int key) {
  19. Guest guest = new Guest();
  20. this.guestMap.put(key, guest);
  21. ByteBuffer byteBuffer = null;
  22. try {
  23. byteBuffer = guest.getData();
  24. } catch (InterruptedException e) {
  25. log.trace("响应超时,事务识别码为:"+key);
  26. }
  27. this.guestMap.remove(key);
  28. return byteBuffer;
  29. }
  30. @Override
  31. public void setData(ByteBuffer bytes) {
  32. if (bytes.remaining() > 2) {
  33. bytes.mark();
  34. int key = new P_AB().decode(bytes).getValue().intValue();
  35. bytes.reset();
  36. if (this.guestMap.containsKey(key)) {
  37. this.guestMap.get(key).setData(bytes);
  38. }else{
  39. log.trace("置入响应数据时,未发现等待者:"+key);
  40. }
  41. }
  42. }
  43. public class Guest {
  44. protected ByteBuffer bytes = null;
  45. public synchronized ByteBuffer getData() throws InterruptedException {
  46. ByteBuffer returnBytes = null;
  47. try {
  48. if (this.bytes == null) {
  49. this.wait(TcpSynchronousWaitingRoom.waitTime);
  50. }
  51. if (this.bytes != null && this.bytes.remaining() != 0) {
  52. returnBytes = this.bytes;
  53. } else {
  54. log.warn("响应超时");
  55. }
  56. } catch (Exception e) {
  57. this.bytes = null;
  58. throw e;
  59. }
  60. this.bytes = null;
  61. return returnBytes;
  62. }
  63. public synchronized void setData(ByteBuffer bytes) {
  64. this.bytes = bytes;
  65. this.notifyAll();
  66. }
  67. }
  68. }