How to create a jabber/XMPP proxy/logging service?
I am working for a company that is using Google Chatback (anonymous chat with a support employee in my company's case) as the main chat service provider. This service uses the XMPP (formerly known as Jabber) protocol for sending and receiving messages.
Our company has ten support employee accounts, and they are accessible through the chatback service we have used on our website. The employees use both Mac OSX and Windows, along with different clients on the different OSes. The chat is also available through native apps on both Android and iOS.
We need a service for logging the chat sessions, and we have been looking into proprietary solutions, but these are not supported on the mobile platforms, and that's basically the dealbreaker.
The solution I have decided is to introduce another link in the message chain, that logs all messages. The idea is that the server sends through this proxy, that logs the messages according to which chat session it is, and then saves those logs in an appropriate manner. Currently they are storing all the logs in a Dropbox folder, which is an error-prone activity.
This would, in theory, allow our supporters to use whatever os/client they chose, and the logs would end up the same place.
Having conducted some tests using the Smack API, I have concluded that my XMPP client (Trillian on both Android and Windows) replies to the resource from which it last received a message. This means effectively that the very simple chat logger I have implemented simply gets ignored.
The test have been conducted using the code below coupled with another client that runs in parallel. Only one of the clients receives the message.
ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "googlemail.com");
config.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
config.setSASLAuthenticationEnabled(true);
XMPPConnection connection = new XMPPConnection(config);
connection.connect();
Presence presence = new Presence(Presence.Type.unavailable);
connection.login("android_client_username", "android_client_pass");
Message message = new Message("my_test_email@gmail.com");
message.setBody("Hello World!");
connection.sendPacket(message);
connection.sendPacket(presence);
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message message = (Message) packet;
System.out.println(message.getBody());
}
}
}, new MessageTypeFilter(Message.Type.chat));
Thank you for your time.
If you DON'T USE the Google Chatback service it is relatively easy to set up the environment you need. In order to log XMPP messages, the chat must be done via MUC (multi-user-chat). You need the following components:
All this stuff can be found in the book, except for Perl script using Net::Jabber.
I was maybe not much of a help but if you decide to go this way, I'll help. If Google Chatback supports MUC, then all you need is Perl/Net::Jabber part.
EDIT: the perl XMPP daemon
#!/usr/bin/perl -w
use strict;
use Net::Jabber;
use threads;
use DBI;
my $server = shift @ARGV;
my $port = shift @ARGV;
my $username = shift @ARGV;
my $password = shift @ARGV;
my $resource = shift @ARGV;
my $chatroom = shift @ARGV;
my %img = ('URGENT' => 'urgent.png',
'HIGH' => 'high.png',
'MEDIUM' => 'medium.png',
'LOW' => 'low.png');
my $dbname_status= 'db';
my $dbuser_status= 'user';
my $dbpass_status= 'pass';
my $dbhost_status = 'localhost';
my $dbport_status = 5432;
my $dbh_status = DBI->connect("dbi:Pg:dbname=$dbname_status;host=$dbhost_status;port=$dbport_status", $dbuser_status, $dbpass_status, {AutoCommit => 0, RaiseError => 1});
my $sth_status = $dbh_status->prepare(qq{SELECT * FROM sosrhs_ticketstatus});
$sth_status->execute;
my %status = ();
while (my $res = $sth_status->fetchrow_hashref)
{
$status{$res->{status}} = $res->{id};
}
$sth_status->finish;
$dbh_status->disconnect;
print "nSERVER: ", $server, "n";
print 'PORT: ', $port, "n";
print 'USERNAME: ', $username, "n";
print 'RESOURCE: ', $resource, "n";
$SIG{HUP} = &Stop;
$SIG{KILL} = &Stop;
$SIG{TERM} = &Stop;
$SIG{INT} = &Stop;
my $Connection = new Net::Jabber::Client();
$Connection->SetCallBacks(message => sub {threads->create('InMessage', (@_))->join()},
presence => sub {threads->create('InPresence', (@_))->join()},
iq => sub {threads->create('InIQ', (@_))->join()}
);
my $status = $Connection->Connect(hostname=>$server,
port=>$port,
);
if (!(defined($status)))
{
print "ERROR: Jabber server is down or connection was not allowed.n";
print " ($!)n";
exit(0);
}
my @result = $Connection->AuthSend(username=>$username,
password=>$password,
resource=>$resource);
if ($result[0] ne "ok")
{
print "ERROR: Authorization failed: $result[0] - $result[1]n";
exit(0);
}
print "Logged in to $server:$port...n";
$Connection->RosterGet();
print "Getting Roster to tell server to send presence info...n";
$Connection->PresenceSend();
print "Sending presence to tell world that we are logged in...n";
$Connection->MUCJoin(room => $chatroom,
server => 'conference.' . $server,
nick => $username);
print 'Join ' . $chatroom . '@conference.sosrhs MUC room...';
print "n";
while(defined($Connection->Process())) { }
print "ERROR: The connection was killed...n";
exit(0);
sub Stop
{
print "Exiting...n";
$Connection->Disconnect();
exit(0);
}
sub InMessage
{
my $sid = shift;
my $message = shift;
my $type = $message->GetType();
my $fromJID = $message->GetFrom("jid");
my $from = $fromJID->GetUserID();
my $resource = $fromJID->GetResource();
my $subject = $message->GetSubject();
my $body = $message->GetBody();
#print "===n";
#print "Message ($type)n";
#print " From: $from ($resource)n";
#print " Subject: $subjectn";
#print " Body: $bodyn";
#print "===n";
#print $message->GetXML(),"n";
#print "===n";
if ($from eq 'ticket_distributor')
{
if ($body =~ /^ticketrelay /)
{
&to_group($body);
}
elsif ($body =~ /^ackrelay /)
{
&to_group_ack($body);
}
elsif ($body =~ /^ticketupdaterelay /)
{
&to_group_update($body);
}
elsif ($body =~ /^ticketwithdrawrelay /)
{
&to_group_withdraw($body);
}
elsif ($body =~ /^ticketclearrelay /)
{
&to_group_clear($body);
}
elsif ($body =~ /^ticketcloserelay /)
{
&to_group_close($body);
}
elsif ($body =~ /^ticketfwdrelay /)
{
&to_group_fwd($body);
}
}
else
{
if ($body =~ /^ticketnew /)
{
&to_group($body);
&to_ticket_distributor($body);
}
elsif ($body =~ /^ack /)
{
&to_ticket_distributor_ack($body);
}
elsif ($body =~ /^ticketupdate /)
{
&to_ticket_distributor_update($body);
}
elsif ($body =~ /^ticketwithdraw /)
{
&to_ticket_distributor_withdraw($body);
}
elsif ($body =~ /^ticketclear /)
{
&to_ticket_distributor_clear($body);
}
elsif ($body =~ /^ticketclose /)
{
&to_ticket_distributor_close($body);
}
elsif ($body =~ /^ticketfwd /)
{
&to_ticket_distributor_fwd($body);
}
}
}
sub InIQ
{
my $sid = shift;
my $iq = shift;
my $from = $iq->GetFrom();
my $type = $iq->GetType();
my $query = $iq->GetQuery();
my $xmlns = $query->GetXMLNS();
#print "===n";
#print "IQn";
#print " From $fromn";
#print " Type: $typen";
#print " XMLNS: $xmlns";
#print "===n";
#print $iq->GetXML(),"n";
#print "===n";
}
sub InPresence
{
my $sid = shift;
my $presence = shift;
my $from = $presence->GetFrom();
my $type = $presence->GetType();
my $status = $presence->GetStatus();
#print "===n";
#print "Presencen";
#print " From $fromn";
#print " Type: $typen";
#print " Status: $statusn";
#print "===n";
#print $presence->GetXML(),"n";
#print "===n";
if ($type eq 'subscribe')
{
my @usrreq = split('@', $from);
my $usrreq = $usrreq[0] . '@' . $server;
$Connection->Subscription(type => 'subscribed',
to => $usrreq
);
}
}
# Functions for actions taken upon ticket
sub to_ticket_distributor
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($msg[1]);
my $group_assigned_groupnamechat = '';
while (my $res = $sth->fetchrow_hashref)
{
$group_assigned_groupnamechat = $res->{group_assigned_groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => $msg[1] . ' ' . $group_assigned_groupnamechat);
}
sub to_ticket_distributor_ack
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1] $msg[2]n";
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->do(qq{UPDATE sosrhs_tickets SET ticketstatus = $status{'WORK IN PROGRESS'}, user_accepted = '$msg[2]', tmstmp_accepted = now() WHERE ticket_id = $msg[1]});
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($msg[1]);
my $user_creator_groups_id = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groups_id = $res->{user_creator_groups_id};
}
$sth->finish;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = ?});
$sth->execute($user_creator_groups_id);
my $user_creator_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ackrelay ' . $msg[1] . ' ' . $user_creator_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ackfinish ' . $msg[1]);
}
sub to_ticket_distributor_update
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1] $msg[2]n";
my $ticket_action = shift @msg;
my $ticket_id = shift @msg;
my $user_id_update = shift @msg;
my $ticket_comment = join(' ', @msg);
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->prepare(qq{INSERT INTO sosrhs_tickets_comments (ticket_id, users_id, comment) VALUES (?, ?, ?)});
$sth->execute($ticket_id, $user_id_update, $ticket_comment);
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($ticket_id);
my $user_creator_groups_id = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groups_id = $res->{user_creator_groups_id};
}
$sth->finish;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = ?});
$sth->execute($user_creator_groups_id);
my $user_creator_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketupdaterelay ' . $ticket_id . ' ' . $user_creator_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketupdatefinish ' . $ticket_id);
}
sub to_ticket_distributor_withdraw
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
my $ticket_action = shift @msg;
my $ticket_id = shift @msg;
my $user_id_withdraw = shift @msg;
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->do(qq{UPDATE sosrhs_tickets SET ticketstatus = $status{'WITHDRAWN'}, user_withdrawn = $user_id_withdraw, tmstmp_withdrawn = now() WHERE ticket_id = $ticket_id});
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($ticket_id);
my $user_creator_groups_id = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groups_id = $res->{user_creator_groups_id};
}
$sth->finish;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = ?});
$sth->execute($user_creator_groups_id);
my $user_creator_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketwithdrawrelay ' . $ticket_id . ' ' . $user_creator_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketwithdrawfinish ' . $ticket_id);
}
sub to_ticket_distributor_clear
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
my $ticket_action = shift @msg;
my $ticket_id = shift @msg;
my $user_id_clear = shift @msg;
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->do(qq{UPDATE sosrhs_tickets SET ticketstatus = $status{'CLEARED'}, user_cleared = $user_id_clear, tmstmp_cleared = now() WHERE ticket_id = $ticket_id});
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($ticket_id);
my $user_creator_groups_id = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groups_id = $res->{user_creator_groups_id};
}
$sth->finish;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = ?});
$sth->execute($user_creator_groups_id);
my $user_creator_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketclearrelay ' . $ticket_id . ' ' . $user_creator_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketclearfinish ' . $ticket_id);
}
sub to_ticket_distributor_close
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
my $ticket_action = shift @msg;
my $ticket_id = shift @msg;
my $user_id_close = shift @msg;
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->do(qq{UPDATE sosrhs_tickets SET ticketstatus = $status{'CLOSED'}, user_closed = $user_id_close, tmstmp_closed = now() WHERE ticket_id = $ticket_id});
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_users_v WHERE groups_id = (SELECT group_assigned_id FROM sosrhs_tickets_v WHERE ticket_id = ?)});
$sth->execute($ticket_id);
my $user_accepted_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_accepted_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketcloserelay ' . $ticket_id . ' ' . $user_accepted_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketclosefinish ' . $ticket_id);
}
sub to_ticket_distributor_fwd
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1] $msg[2]n";
my $ticket_action = shift @msg;
my $ticket_id = shift @msg;
my $user_id_fwd = shift @msg;
my $group_id_fwd_to = shift @msg;
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->do(qq{UPDATE sosrhs_tickets SET ticketstatus = $status{'ASSIGNED'}, user_accepted = NULL, tmstmp_accepted = NULL, group_assigned = $group_id_fwd_to WHERE ticket_id = $ticket_id});
$dbh->commit;
$sth = $dbh->prepare(qq{INSERT INTO sosrhs_tickets_comments (ticket_id, users_id, groups_id_fwd_to) VALUES (?, ?, ?)});
$sth->execute($ticket_id, $user_id_fwd, $group_id_fwd_to);
$dbh->commit;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = (SELECT group_assigned_id FROM sosrhs_tickets_v WHERE ticket_id = ?)});
$sth->execute($ticket_id);
my $user_fwd_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_fwd_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$sth = $dbh->prepare(qq{SELECT groupnamechat FROM sosrhs_groups WHERE id = (SELECT user_creator_groups_id FROM sosrhs_tickets_v WHERE ticket_id = ?)});
$sth->execute($ticket_id);
my $user_creator_groupchatname = '';
while (my $res = $sth->fetchrow_hashref)
{
$user_creator_groupchatname = $res->{groupnamechat};
}
$sth->finish;
$dbh->disconnect;
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketfwdrelay ' . $ticket_id . ' ' . $user_fwd_groupchatname);
$Connection->MessageSend(to => 'ticket_distributor@' . $server,
type => 'chat',
body => 'ticketfwdrelay ' . $ticket_id . ' ' . $user_creator_groupchatname);
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketfwdfinish ' . $ticket_id);
}
# Functions for relayed actions from ticket_distributor
sub to_group
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => &build_new_ticket_message($msg[1]));
}
sub to_group_ack
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ackrelay ' . $msg[1]);
}
sub to_group_update
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketupdaterelay ' . $msg[1]);
}
sub to_group_withdraw
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketwithdrawrelay ' . $msg[1]);
}
sub to_group_clear
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketclearrelay ' . $msg[1]);
}
sub to_group_close
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketcloserelay ' . $msg[1]);
}
sub to_group_fwd
{
my $msg = shift;
my @msg = split(' ', $msg);
print "n$username : $msg[0] $msg[1]n";
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => 'ticketfwdrelay ' . $msg[1]);
sleep 2;
$Connection->MessageSend(to => $chatroom . '@conference.' . $server,
type => 'groupchat',
body => &build_new_ticket_message($msg[1]));
}
sub build_new_ticket_message
{
my $ticket_id = shift;
my $dbname= 'db';
my $dbuser= 'user';
my $dbpass= 'pass';
my $dbhost = 'localhost';
my $dbport = 5432;
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport", $dbuser, $dbpass, {AutoCommit => 0, RaiseError => 1});
my $sth = $dbh->prepare(qq{SELECT * FROM sosrhs_tickets_v where ticket_id = ?});
$sth->execute($ticket_id);
my %ticket = ();
while (my $res = $sth->fetchrow_hashref)
{
$ticket{ticket_id} = $res->{ticket_id};
$ticket{ticketcategory_category} = $res->{ticketcategory_category};
$ticket{ticketstatus_status} = $res->{ticketstatus_status};
$ticket{ticketpriority_severityname} = $res->{ticketpriority_severityname};
$ticket{tmstmp_assigned} = $res->{tmstmp_assigned};
$ticket{user_creator_firstname} = $res->{user_creator_firstname};
$ticket{user_creator_secondname} = $res->{user_creator_secondname};
$ticket{group_assigned_groupname} = $res->{group_assigned_groupname};
$ticket{ticket_text} = $res->{ticket_text};
$ticket{ticket_file} = $res->{ticket_file};
$ticket{subject} = $res->{subject};
$ticket{user_creator_groups_id} = $res->{user_creator_groups_id};
}
$sth->finish;
$dbh->disconnect;
my $html_msg = q!<p id="p! . $ticket{ticket_id} . q!">
<img src="/sosrhs/images/! . $img{$ticket{ticketpriority_severityname}} . q!"/> <text id="t! . $ticket{ticket_id} . q!" class="textmainleft">! . substr($ticket{tmstmp_assigned}, 0, 16) . ' | ' . $ticket{ticketstatus_status} . ' | ' . $ticket{ticketcategory_category} . ' | ' . $ticket{subject} . '<br>From: ' . $ticket{user_creator_firstname} . ' ' . $ticket{user_creator_secondname} . ' | To: ' . $ticket{group_assigned_groupname} . q!</text> | <a href="#" onClick="$('#explanation').fadeOut('fast'); $('div.divmainleft > p').css('background-color', 'white'); $('#p! . $ticket{ticket_id} . q!').css('background-color', '#E0E0F8'); $('#tdexplanation').load('/cgi-bin/sosrhs/ticket_details.pl?ticket_id=! . $ticket{ticket_id} . q!&my_groupchatname=! . $chatroom . q!');">Details</a>
</p>!;
#<hr id="h! . $ticket{ticket_id} . q!" style="height: 1px; border-width: 0; color: gray; background-color: gray;"/>!;
return $html_msg;
}
为什么不使用HTTP上的XMPP,然后使用HTTP代理记录消息(将所有XMPP客户端设置为与HTTP代理而不是直接对话)?
I am not too sure if it will affect you and your service, but just for your information in past i have experienced 407 Proxy Auth. response code while trying to make cross domain text/xml ajax requests. Mostly if you are behind a firewall/http-proxy(squid) kind of environment. Solution to that is mostly fallback mode to jsonp when behind a proxy.
Test Verify: 1) setup local squid 2) use strophejs basic examples 3) setup cross domain ajax ie BOSH_SERVICE_URL domain is not same as requestor domain 4) configure browser to use local squid 5) You will find all POST api calls ie /http-bind text/xml calls will fail with 407 proxy auth response code 6) remove proxy-usage from browser 7) try again, everything works with CORS enabled
链接地址: http://www.djcxy.com/p/16816.html上一篇: Jabber和昂贵的数据(xml其垃圾)