DialogMaster.pm.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. package Bus::DialogMaster;
  2. use strict;
  3. use Scalar::Util qw(refaddr);
  4. use Modules 'register';
  5. use Bus::Query;
  6. use constant {
  7. STARTING   => 1,
  8. ENGAGED    => 2,
  9. TERMINATED => 3,
  10. TIMEOUT    => 4
  11. };
  12. # struct Bus::Dialog {
  13. #     Bus::Client bus;
  14. #     Bytes  peerID;
  15. #     Bytes  dialogID;
  16. #     Bytes  peerDialogID;
  17. #     String reason;
  18. #     Hash   args;
  19. #     int    timeout;
  20. #     int    state;
  21. # }
  22. sub new {
  23. my ($class, $args) = @_;
  24. my $self = bless $args, $class;
  25. my $bus = $self->{bus};
  26. $self->{timeout} ||= 5;
  27. $self->{receivedEvent} = $bus->onMessageReceived->add($self, &messageReceived);
  28. $self->{query} = $bus->query("REQUEST_DIALOG", {
  29. TO       => $self->{peerID},
  30. reason   => $self->{reason},
  31. dialogID => refaddr($self),
  32. %{$self->{args}}
  33. }, {
  34. timeout => $self->{timeout}
  35. }
  36. );
  37. $self->{state} = STARTING;
  38. return $self;
  39. }
  40. sub DESTROY {
  41. my ($self) = @_;
  42. $self->{bus}->onMessageReceived->remove($self->{receivedEvent});
  43. }
  44. sub iterate {
  45. my ($self) = @_;
  46. if ($self->{state} == STARTING) {
  47. # Waiting for peer to accept dialog.
  48. my $query = $self->{query};
  49. if ($query->getState() == Bus::Query::DONE) {
  50. print "DialogMaster - Got reply for dialog requestn";
  51. my ($MID, $args) = $query->getReply();
  52. if ($MID eq "ACCEPTED") {
  53. # Dialog accepted.
  54. print "DialogMaster - Dialog acceptedn";
  55. $self->{state} = ENGAGED;
  56. $self->{peerDialogID} = $args->{dialogID};
  57. } else {
  58. # Dialog not accepted.
  59. print "DialogMaster - Dialog refusedn";
  60. $self->{state} = TERMINATED;
  61. }
  62. delete $self->{query};
  63. } elsif ($query->getState() == Bus::Query::TIMEOUT) {
  64. # Dialog not approved within time limit.
  65. print "DialogMaster - Start timeoutn";
  66. $self->{state} = TIMEOUT;
  67. delete $self->{query};
  68. }
  69. } elsif ($self->{state} == ENGAGED && (my $query = $self->{query})) {
  70. if ($query->getState() == Bus::Query::DONE) {
  71. my @reply = $query->getReply();
  72. $self->{reply} = @reply;
  73. delete $self->{query};
  74. } elsif ($query->getState() == Bus::Query::TIMEOUT) {
  75. $self->{state} = TIMEOUT;
  76. delete $self->{query};
  77. }
  78. }
  79. }
  80. sub getState {
  81. my ($self) = @_;
  82. $self->iterate();
  83. return $self->{state};
  84. }
  85. ##
  86. # $Bus_Dialog->query(String messageID, args, Hash options)
  87. sub query {
  88. my ($self, $MID, $args, $options) = @_;
  89. $self->iterate();
  90. if ($self->{query} || $self->{reply}) {
  91. die "Do not send another query without receiving the previous reply first.";
  92. } else {
  93. my %args2 = ($args) ? %{$args} : ();
  94. $args2{TO}       = $self->{peerID};
  95. $args2{dialogID} = $self->{peerDialogID};
  96. $self->{query} = $self->{bus}->query($MID, %args2, $options);
  97. }
  98. }
  99. ##
  100. # Tuple $Bus_Dialog->getReply()
  101. #
  102. # Returns a an array with two items: the message ID and the message arguments.
  103. sub getReply {
  104. my ($self) = @_;
  105. $self->iterate();
  106. my $reply = $self->{reply};
  107. delete $self->{reply};
  108. return @{$reply};
  109. }
  110. sub messageReceived {
  111. my ($self, undef, $message) = @_;
  112. my $state = $self->{state};
  113. my $MID   = $message->{messageID};
  114. my $args  = $message->{args};
  115. if (($state == STARTING || $state == ENGAGED) && $MID eq 'LEAVE' && $args->{clientID} eq $self->{peerID}) {
  116. $self->iterate();
  117. $self->{state} = TERMINATED;
  118. }
  119. }
  120. 1;