#!/usr/bin/perl
+# -------------------------------------------------------------
+# Copyright (C) 2016, King County Library System
+# Bill Erickson <berickxx@gmail.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+# -------------------------------------------------------------
+# Sample script using WebSockets transport.
+# -------------------------------------------------------------
use strict;
use warnings;
-use OpenSRF::System;
-use OpenSRF::AppSession;
use OpenSRF::DomainObject::oilsMethod;
use OpenSRF::DomainObject::oilsMessage;
use OpenSRF::Transport::WebSockets::Client;
-my $osrf_config = '/openils/conf/opensrf_core.xml';
-
-# note: for now this still connects to jabber.
-OpenSRF::System->bootstrap_client(config_file => $osrf_config);
-
my $method = OpenSRF::DomainObject::oilsMethod->new(
method => 'opensrf.system.echo',
params => ['hello, world']
# connects to localhost by default
my $client = OpenSRF::Transport::WebSockets::Client->new(
- 'no-op',
+ 'ignored',
host => 'localhost',
port => 7682,
ssl_no_verify => 1,
die "cound not connect\n" unless $client->connect;
-$client->send(
- to => 'open-ils.auth',
- thread => rand(),
- msg => [$msg]
-);
+my $idx = 0;
+while ($idx++ < 5) {
+
+ $client->send(
+ to => 'open-ils.auth',
+ thread => rand(),
+ msg => [$msg]
+ );
-my $response = $client->recv(-1);
+ my $response = $client->recv(-1);
-for my $msg (@{$response->{msg}}) {
- print "received: " .
- OpenSRF::Utils::JSON->perl2JSON($msg) . "\n\n";
+ for my $msg (@{$response->{msg}}) {
+ print "RECEIVED: " . $msg->type . "\n";
+ if ($msg->type eq 'RESULT') {
+ print "_-=> " . $msg->payload->content . "\n";
+ }
+ }
}
+$client->disconnect;
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# -------------------------------------------------------------
+# WebSockets Client.
+# Only works in manual/client mode, pending changes to higher-
+# level code to support connecting without requiring access
+# to the settings server.
+# -------------------------------------------------------------
use strict;
use warnings;
use IO::Socket::SSL;
use Data::Dumper;
$Data::Dumper::INDENT=0;
-
+# Shared connection required by OpenSRF in some contexts.
+# Can be bypassed in new().
our $connection;
sub retrieve {
}
+# $app is ignored in client (non-server) mode
sub new {
my ($class, $app, %args) = @_;
return $connection if
- $connection && $connection->{socket}->connected;
+ !$args{force_new} &&
+ $connection &&
+ $connection->{socket}->connected;
+
+ my $host = $args{host};
+ my $port = $args{port};
+ my $path = $args{path};
+ # In client-only mode, there may be no bootstrap config.
my $conf = OpenSRF::Utils::Config->current;
+ if ($conf) {
+ $host ||= $conf->bootstrap->domain;
+ $port ||= $conf->bootstrap->port;
+ $path ||= $conf->bootstrap->path;
+ }
+
+ # Finally apply defaults
+ $host ||= 'localhost';
+ $port ||= 7682;
+ $path ||= '/osrf-websocket-translator';
my $self = {
service => $app,
- host => $args{host} || $conf->bootstrap->domain || 'localhost',
- port => $args{port} || $conf->bootstrap->domain || 7682,
- path => $args{path} || $conf->bootstrap->path || '/osrf-websocket-translator',
+ host => $host,
+ port => $port,
+ path => $path,
connected => 0,
responses => [],
ssl_params => {}
};
- $self->{ssl_params} = {SSL_verify_mode => SSL_VERIFY_NONE}
- if ($args{ssl_no_verify} || $conf->bootstrap->ssl_no_verify);
+ $self->{ssl_params} = {SSL_verify_mode => SSL_VERIFY_NONE} if (
+ $args{ssl_no_verify} ||
+ ($conf && $conf->bootstrap->ssl_no_verify)
+ );
$connection = bless($self, $class);
return $connection;
};
$logger->debug("WebSocket socket args: " . Dumper($sock_args));
- warn "WebSocket socket args: " . Dumper($sock_args) . "\n";
my $sock = IO::Socket::SSL->new(%$sock_args);
- return $self->{socket} = $sock if $sock && $sock->connected;
+ unless ($sock && $sock->connected) {
+
+ $logger->error("SSL socket connection failed for ".
+ $self->{host}.":".$self->{port}." => $!");
- warn "SSL socket connection failed to ".
- $self->{host}.":".$self->{port}." => $!\n";
+ return undef;
+ }
- return undef;
+ return $self->{socket} = $sock;
}
# true if a connection exists and the TCP port is open.
sub tcp_connected {
- return
- $connection &&
- $connection->{socket} &&
- $connection->{socket}->connected;
+ my $self = shift;
+ return $self->{socket} && $self->{socket}->connected;
}
# true if we have completed the websockets handshake w/ the server
return $self->tcp_connected && $self->{connected};
}
-# returns a message if one is availabe or becomes available
-# within the timeout provided. A timeout value of 0 or undef
-# means check for messages, but don't wait. A timeout of -1 means
-# wait until a message arrives. A timeout of > 0 means to wait
-# the many seconds for a message to arrive.
+# OpenSRF method; checks for received messages.
sub process {
my $self = shift;
return $self->recv(@_);
sub disconnect {
my $self = shift;
$self->{connected} = 0;
- return unless $self->{client};
- $self->{client}->disconnect;
- delete $self->{client};
+
+ if ($self->{client}) {
+ $self->{client}->disconnect;
+ delete $self->{client};
+ }
+
+ if ($self->{socket}) {
+ $self->{socket}->close;
+ $self->{socket}->shutdown(2);
+ delete $self->{socket};
+ }
+}
+
+# Read and discard all messages from the socket (without blocking).
+# Returns 1 on success, 0 if not connected.
+sub flush_socket {
+ my $self = shift;
+ return 0 unless $self->connected;
+
+ while ($self->recv(0)) {
+ $logger->debug("flushing data from socket...");
+ }
+
+ return $self->connected;
}