OpenSRF client disconnect robustification (Perl)
[OpenSRF.git] / src / perl / lib / OpenSRF / Transport / SlimJabber / Client.pm
1 package OpenSRF::Transport::SlimJabber::Client;
2
3 use strict;
4 use warnings;
5
6 use OpenSRF::EX;
7 use OpenSRF::Utils::Config;
8 use OpenSRF::Utils::Logger qw/$logger/;
9 use OpenSRF::Transport::SlimJabber::XMPPReader;
10 use OpenSRF::Transport::SlimJabber::XMPPMessage;
11 use IO::Socket::INET;
12
13 =head1 NAME
14
15 OpenSRF::Transport::SlimJabber::Client
16
17 =head1 SYNOPSIS
18
19
20
21 =head1 DESCRIPTION
22
23
24
25 =cut
26
27 =head1 METHODS
28
29 =head2 new
30
31 =cut
32
33 sub new {
34         my( $class, %params ) = @_;
35     my $self = bless({}, ref($class) || $class);
36     $self->params(\%params);
37         return $self;
38 }
39
40 =head2 reader
41
42 =cut
43
44 sub reader {
45     my($self, $reader) = @_;
46     $self->{reader} = $reader if $reader;
47     return $self->{reader};
48 }
49
50 =head2 params
51
52 =cut
53
54 sub params {
55     my($self, $params) = @_;
56     $self->{params} = $params if $params;
57     return $self->{params};
58 }
59
60 =head2 socket
61
62 =cut
63
64 sub socket {
65     my($self, $socket) = @_;
66     $self->{socket} = $socket if $socket;
67     return $self->{socket};
68 }
69
70 =head2 disconnect
71
72 =cut
73
74 sub disconnect {
75     my $self = shift;
76         $self->reader->disconnect if $self->reader;
77 }
78
79
80 =head2 gather
81
82 =cut
83
84 sub gather { 
85     my $self = shift; 
86     $self->process( 0 ); 
87 }
88
89 # -------------------------------------------------
90
91 =head2 tcp_connected
92
93 =cut
94
95 sub tcp_connected {
96         my $self = shift;
97     return $self->reader->tcp_connected if $self->reader;
98     return 0;
99 }
100
101 sub connected {
102     my $self = shift;
103     return $self->reader->connected if $self->reader;
104     return 0;
105 }
106
107
108 =head2 send
109
110 =cut
111
112 sub send {
113         my $self = shift;
114     my $msg = OpenSRF::Transport::SlimJabber::XMPPMessage->new(@_);
115     $msg->osrf_xid($logger->get_osrf_xid);
116     $msg->from($self->xmpp_id);
117     my $xml = $msg->to_xml;
118     { 
119         use bytes; 
120         my $len = length($xml);
121         if ($len >= $self->{msg_size_warn}) {
122             $logger->warn("Sending large message of $len bytes to " . $msg->to)
123         }
124     }
125     $self->reader->send($xml);
126 }
127
128 =head2 initialize
129
130 =cut
131
132 sub initialize {
133
134         my $self = shift;
135
136         my $host        = $self->params->{host}; 
137         my $port        = $self->params->{port}; 
138         my $username    = $self->params->{username};
139         my $resource    = $self->params->{resource};
140         my $password    = $self->params->{password};
141
142         my $conf = OpenSRF::Utils::Config->current;
143
144     $self->{msg_size_warn} = $conf->bootstrap->msg_size_warn || 1800000;
145
146         my $tail = "_$$";
147         $tail = "" if !$conf->bootstrap->router_name and $username eq "router";
148     $resource = "$resource$tail";
149
150     my $socket = IO::Socket::INET->new(
151         PeerHost => $host,
152         PeerPort => int($port),
153         Proto  => 'tcp' );
154
155     throw OpenSRF::EX::Jabber("Could not open TCP socket to Jabber server: $@")
156             unless ( $socket and $socket->connected );
157
158     $self->socket($socket);
159     $self->reader(OpenSRF::Transport::SlimJabber::XMPPReader->new($socket));
160     $self->reader->connect($host, $username, $password, $resource);
161
162     throw OpenSRF::EX::Jabber("Could not authenticate with Jabber server: $@")
163             unless ( $self->reader->connected );
164
165     $self->xmpp_id("$username\@$host/$resource");
166     $logger->debug("Created XMPP connection " . $self->xmpp_id);
167         return $self;
168 }
169
170
171 # Our full login:  username@host/resource
172 sub xmpp_id {
173     my($self, $xmpp_id) = @_;
174     $self->{xmpp_id} = $xmpp_id if $xmpp_id;
175     return $self->{xmpp_id};
176 }
177
178
179 =head2 construct
180
181 =cut
182
183 sub construct {
184         my( $class, $app ) = @_;
185         $class->peer_handle($class->new( $app )->initialize());
186 }
187
188
189 =head2 process
190
191 =cut
192
193 sub process {
194         my($self, $timeout) = @_;
195
196         $timeout ||= 0;
197     $timeout = int($timeout);
198
199         unless( $self->reader and $self->reader->connected ) {
200         throw OpenSRF::EX::JabberDisconnected 
201             ("This JabberClient instance is no longer connected to the server ");
202         }
203
204     return $self->reader->wait_msg($timeout);
205 }
206
207
208 =head2 flush_socket
209
210 Sets the socket to O_NONBLOCK, reads all of the data off of the
211 socket, the restores the sockets flags.  Returns 1 on success, 0 if
212 the socket isn't connected.
213
214 =cut
215
216 sub flush_socket {
217         my $self = shift;
218     return 0 unless $self->reader;
219     return $self->reader->flush_socket;
220 }
221
222 1;
223
224