📄 session.java
字号:
/* * Copyright (C) 2005 Stefan Strigler <steve@zeank.in-berlin.de> * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */package org.jabber.JabberHTTPBind;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.StringReader;import java.io.StringWriter;import java.net.Socket;import java.net.UnknownHostException;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Random;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;/** * this class reflects a session within http binding definition * * @author Stefan Strigler <steve@zeank.in-berlin.de> */public class Session{ /* * ####### CONSTANTS ####### */ public static final int MAX_WAIT = 60; public static final int MAX_HOLD = 2; public static final int MIN_POLLING = 5; public static final int MAX_INACTIVITY = 60; public static final String DEFAULT_CONTENT = "text/xml; charset=utf-8"; private static final int READ_TIMEOUT = 1; /* * ####### static ####### */ private static int CNT = 0; private static Hashtable sessions = new Hashtable(); private static String createSessionID(int len) { String charlist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; Random rand = new Random(); String str = new String(); for (int i = 0; i < len; i++) str += charlist.charAt(rand.nextInt(charlist.length())); return str; } public static Session getSession(String sid) { return (Session) sessions.get(sid); } public static Enumeration getSessions() { return sessions.elements(); } public static void stopSessions() { for (Enumeration e = sessions.elements(); e.hasMoreElements(); ) ((Session) e.nextElement()).terminate(); } /* * ####### END static ####### */ private String sid; private String to; private String authid; // stream id given by remote jabber server private int hold = MAX_HOLD; private int wait = MAX_WAIT; private String xmllang = "en"; private String content = DEFAULT_CONTENT; private Socket sock; private OutputStreamWriter osw; private InputStreamReader isr; private String inQueue = ""; private DocumentBuilder db; private Date cDate; private long lastActive; private static TransformerFactory tff = TransformerFactory.newInstance(); public Session(String to) throws UnknownHostException, IOException { CNT++; // don't know - might be useable for debugging or so this.to = to; this.cDate = new Date(); this.lastActive = System.currentTimeMillis(); try { this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (Exception e) {} // connect to jabber server try { this.sock = new Socket(to, 5222); if (JHBServlet.DEBUG && this.sock.isConnected()) System.err.println("Succesfully connected to " + to); // instantiate <stream> this.osw = new OutputStreamWriter(this.sock.getOutputStream(),"UTF-8"); this.osw.write( "<stream:stream to='" + this.to + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"); this.osw.flush(); // create session id while (sessions.get(this.sid = createSessionID(24)) != null); if (JHBServlet.DEBUG) System.err.println("creating session with id " + this.sid); // register session sessions.put(this.sid, this); this.isr = new InputStreamReader(this.sock.getInputStream(),"UTF-8"); String stream = this.readFromSocket(); Pattern p = Pattern.compile(".*\\<stream\\:stream.*id=['\"]([^'\"]+)['\"].*"); Matcher m = p.matcher(stream); if (m.matches()) this.authid = m.group(1); else this.authid = ""; } catch (UnknownHostException uhe) { throw uhe; } catch (IOException ioe) { throw ioe; } } public Session(String to, int hold, int wait, String xmllang) throws UnknownHostException, IOException { this(to); this.setHold(hold); this.setWait(wait); this.setXMLLang(xmllang); } /** * sends all nodes in list to remote jabber server * * @param nl list of nodes to send * @return the session itself */ public Session sendNodes(NodeList nl) { // build a string String out = ""; StreamResult strResult = new StreamResult(); try { Transformer tf = tff.newTransformer(); tf.setOutputProperty("omit-xml-declaration", "yes"); // loop list for (int i=0; i<nl.getLength(); i++) { strResult.setWriter(new StringWriter()); tf.transform(new DOMSource(nl.item(i)), strResult); String tStr = strResult.getWriter().toString(); out += tStr; } } catch (Exception e) { System.err.println("XML.toString(Document): " + e); } try { this.osw.write(out); this.osw.flush(); } catch (IOException ioe) { System.err.println(this.sid + " failed to write to stream"); } this.touch(); return this; } /** * reads from socket * @return string that was read */ private String readFromSocket() { String retval = ""; char buf[] = new char[16]; int c=0; while (!this.sock.isClosed()) { try { if (this.isr.ready()) { while (this.isr.ready() && (c = this.isr.read(buf, 0, buf.length)) >= 0) { retval += new String(buf,0,c); } break; } else { if (this.hold == 1) break; try { Thread.sleep(READ_TIMEOUT); } catch (InterruptedException ie) { System.err.println(ie.toString()); } } this.touch(); } catch (IOException e) { System.err.println("Can't read from socket"); this.terminate(); } } this.touch(); return retval; } /** * checks InputStream from server for incoming packets * blocks until request timeout or packets available * * @return nl - NodeList of incoming Nodes */ public NodeList checkInQ() { NodeList nl = null; inQueue += this.readFromSocket(); // try to parse it if (!inQueue.equals("")) { try { /* wrap inQueue with element so that multiple nodes * can be parsed */ Document doc = db.parse(new InputSource(new StringReader( "<doc xmlns='jabber:client'>" + inQueue + "</doc>"))); nl = doc.getFirstChild().getChildNodes(); inQueue = ""; // reset! } catch (Exception e3) { System.err.println("checkInQ: failed to parse: " + e3.toString()); } } return nl; } /** * set lastActive to current timestamp * * @return this */ public Session touch() { this.lastActive = System.currentTimeMillis(); return this; } /** * kill this session * */ public void terminate() { try { this.sock.close(); } catch (IOException ie) {} sessions.remove(this.sid); } /* * ######## getters ######### */ public String getTo() { return this.to; } public String getAuthid() { return this.authid; } public int getHold() { return this.hold; } public int getWait() { return this.wait; } public String getXMLLang() { return this.xmllang; } public String getSID() { return this.sid; } public String getContent() { return this.content; } public long lastActive() { return this.lastActive; } /* * ######## setters ######### */ public Session setHold(int hold) { if (hold < MAX_HOLD) this.hold = hold; return this; } public Session setWait(int wait) { if (wait < MAX_WAIT) this.wait = wait; return this; } public Session setXMLLang(String xmllang) { this.xmllang = xmllang; return this; } public Session setContent(String content) { this.content = content; return this; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -