xmppclient.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 723 行 · 第 1/2 页

JAVA
723
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.xmpp;import com.caucho.bam.*;import com.caucho.server.connection.*;import com.caucho.server.port.*;import com.caucho.util.*;import com.caucho.vfs.*;import com.caucho.xmpp.im.*;import java.io.IOException;import java.io.Serializable;import java.net.*;import java.util.*;import java.util.concurrent.*;import java.util.logging.*;import javax.xml.stream.*;/** * XMPP protocol */public class XmppClient {  private static final L10N L = new L10N(XmppClient.class);  private static final Logger log    = Logger.getLogger(XmppClient.class.getName());  private static final String STREAMS_NS = "http://etherx.jabber.org/streams";  private static final String AUTH    = "auth{http://jabber.org/features/iq-auth}";  private static final String REGISTER    = "register{http://jabber.org/features/iq-register}";  private InetAddress _address;  private int _port;    private String _to;  private Socket _s;  private ReadStream _is;  private WriteStream _os;  private String _id;  private String _from;    private XmppStreamReader _in;  private XmppReader _reader;    private boolean _isFinest;  private int _mId;  private HashSet<String> _authMechanisms = new HashSet<String>();  private HashSet<String> _features = new HashSet<String>();  private BlockingQueue<Stanza> _stanzaQueue    = new LinkedBlockingQueue<Stanza>();  private XmppContext _xmppContext = new XmppContext();  private XmppClientBrokerStream _toBroker;  private BindCallback _bindCallback;  private String _jid;    private BamStream _callback;  public XmppClient(InetAddress address, int port)  {    _address = address;    _port = port;    _to = _address.getHostAddress();    _isFinest = log.isLoggable(Level.FINEST);  }					     public XmppClient(String address, int port)  {    this(getByName(address), port);        _to = address;  }  private static InetAddress getByName(String address)  {    try {      return InetAddress.getByName(address);    } catch (Exception e) {      throw new RuntimeException(e);    }  }  public void connect()    throws IOException  {    try {      if (_s != null)	throw new IllegalStateException(L.l("{0} is already connected", this));      _s = new Socket(_address, _port);      SocketStream ss = new SocketStream(_s);          _os = new WriteStream(ss);      _is = new ReadStream(ss);      _os.print("<?xml version='1.0' encoding='UTF-8' ?>\n");      _os.setEncoding("utf-8");            startStream();      _os.flush();            XMLInputFactory factory = XMLInputFactory.newInstance();      XmppMarshalFactory marshalFactory = new XmppMarshalFactory();            XmppStreamWriterImpl out;      out = new XmppStreamWriterImpl(_os, marshalFactory);      XmppWriter writer = new XmppWriter(_xmppContext, out);            _toBroker = new XmppClientBrokerStream(this, writer);          _in = new XmppStreamReaderImpl(_is, marshalFactory);      _bindCallback = new BindCallback();      _reader = new XmppReader(_xmppContext, _is, _in, _toBroker,			       _bindCallback);      String tag = readStartTag();      if (! tag.equals("stream")	  || ! STREAMS_NS.equals(_in.getNamespaceURI())) {	throw new IOExceptionWrapper(L.l("<{0}> with ns={1} is an unexpected server response",				  tag, _in.getNamespaceURI()));      }      readStreamFeatures();    } catch (XMLStreamException e) {      throw new IOExceptionWrapper(e);    }  }    public void login(String name, String password)    throws IOException  {    String base64 = Base64.encode("" + (char) 0 + name + (char) 0 + password);    if (log.isLoggable(Level.FINER))      log.finer(this + " authenticating " + name);    _os.print("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>");    _os.print(base64);    _os.print("</auth>");    startStream();    _os.flush();    try {      if (! readSuccess())	throw new RuntimeException("expected success");            if (! readStream())	throw new RuntimeException("expected stream");      StringBuilder sb = new StringBuilder();      Base64.encode(sb, RandomUtil.getRandomLong());            _os.print("<iq type='set' id='" + _mId++ + "'>");      _os.print("<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>");      _os.print("<resource>" + getClass().getSimpleName() + "</resource>");      _os.print("</bind>");      _os.print("</iq>");      _os.flush();      _reader.readNext();      if (_jid == null)	throw new RuntimeException("expected bind");            _os.print("<iq type='set' id='" + _mId++ + "'>");      _os.print("<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>");      _os.print("</iq>");      _os.flush();      _reader.readNext();      /*      Stanza stanza = _stanzaQueue.poll(2, TimeUnit.SECONDS);      if (! (stanza instanceof SessionStanza)	  && ! (stanza instanceof EmptyStanza))	throw new RuntimeException("expected session");      */      if (log.isLoggable(Level.FINER))	log.finer(this + " authentication successful for " + name);      _reader.setHandler(_callback);      ThreadPool.getThreadPool().start(new Listener());    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw new RuntimeException(e);    }  }  public void setCallback(BamStream callback)  {    _callback = callback;    if (_reader != null && _jid != null)      _reader.setHandler(callback);  }    public void send(String type, String to, String body)    throws IOException  {    send(type, to, body, null);  }    public void send(String type, String to, String body, String subject)    throws IOException  {    if (log.isLoggable(Level.FINER))      log.finer(this + " send to=" + to + " body=" + body);    try {      _os.print("<message ");      _os.print(" type='" + type + "'");            if (to != null)	_os.print(" to='" + to + "'");      if (_from != null)	_os.print(" from='" + _from + "'");      _os.print(">");            if (subject != null)	_os.print("<subject>" + subject + "</subject>");      if (body != null)	_os.print("<body>" + body + "</body>");      _os.print("</message>");      _os.flush();    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw new RuntimeException(e);    }  }  private void startStream()    throws IOException  {    _os.print("<stream:stream");    _os.print(" to='" + _to + "'");    _os.print(" xmlns='jabber:client'");    _os.print(" xmlns:stream='http://etherx.jabber.org/streams'");    _os.print(" version='1.0'");    _os.print(">");    _os.flush();    if (log.isLoggable(Level.FINER))      log.finer(this + " <stream:stream xmlns='jabber:client' to='" + _to + "'>");  }  private void readStreamFeatures()    throws IOException, XMLStreamException  {    String startTag = readStartTag();    if (! "features".equals(startTag))      throw unexpected();    int tag = 0;        while ((tag = _in.next()) > 0	   && ! (tag == XMLStreamReader.END_ELEMENT		 && "features".equals(_in.getLocalName()))) {      if (_isFinest)	debug(_in);            if (tag == XMLStreamReader.START_ELEMENT) {	String localName = _in.getLocalName();	if ("mechanisms".equals(localName)) {	}	else if ("mechanism".equals(localName)) {	  tag = _in.next();	  	  String mechanism = _in.getText();	  _authMechanisms.add(mechanism);	}	else {	  String feature = localName + "{" + _in.getNamespaceURI() + "}";	  if (log.isLoggable(Level.FINER))	    log.finer(this + " feature " + feature);	  _features.add(feature);	}      }      else if (tag == XMLStreamReader.END_ELEMENT) {	String localName = _in.getLocalName();      }    }  }  private String readStartTag()    throws IOException, XMLStreamException  {    int tag = 0;        while ((tag = _in.next()) > 0 && tag != XMLStreamReader.START_ELEMENT) {      if (_isFinest)	debug(_in);    }        if (_isFinest)      debug(_in);    return _in.getLocalName();      }  private IOException unexpected()    throws IOException, XMLStreamException  {    if ("error".equals(_in.getLocalName())) {      int tag;            while ((tag = _in.next()) > 0	     && ! (tag == XMLStreamReader.END_ELEMENT

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?