Session类构造方法初解

/**
	 * Create a new session and connect to jabber server host denoted by
	 * <code>route</code> or <code>to</code>.
	 * 
	 * @param to
	 *            domain of the server to connect to.
	 * @param route
	 *            optional hostname of the server to connect to (might be null).
	 * 
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public Session(String to, String route) throws UnknownHostException,
			IOException {
		this.to = to;

		int port = DEFAULT_XMPPPORT;

		this.sock = new Socket();
		this.setLastActive();

		try {
			this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch (Exception e) {
		}

		// first, try connecting throught the 'route' attribute.
		if (route != null && !route.equals("")) {
			JHBServlet.dbg(
					"Trying to use 'route' attribute to open a socket...", 3);
			if (route.startsWith("xmpp:")) {
				route = route.substring("xmpp:".length());
			}

			int i;
			// has 'route' the optional port?
			if ((i = route.lastIndexOf(":")) != -1) {
				try {
					int p = Integer.parseInt(route.substring(i + 1));
					if (p >= 0 && p <= 65535) {
						port = p;
						JHBServlet.dbg(
								"...route attribute holds a valid port ("
										+ port + ").", 3);
					}
				} catch (NumberFormatException nfe) {
				}

				route = route.substring(0, i);
			}

			JHBServlet.dbg("Trying to open a socket to '" + route
					+ "', using port " + port + ".", 3);

			try {
				this.sock.connect(new InetSocketAddress(route, port),
						SOCKET_TIMEOUT);
			} catch (Exception e) {
				JHBServlet.dbg(
						"Failed to open a socket using the 'route' attribute",
						3);
				/*
				 * none of the exceptions possible should be reason to throw
				 * anything. If the socket isn't opened, we'll get a retry using
				 * the 'to' attribute anyway.
				 */
			}
		}

		// If no socket has been opened, try connecting trough the 'to'
		// attribute.
		if (this.sock == null || !this.sock.isConnected()) {
			JHBServlet.dbg("Trying to use 'to' attribute to open a socket...",
					3);
			host = DNSUtil.resolveXMPPServerDomain(to, DEFAULT_XMPPPORT);
			try {
				JHBServlet.dbg("Trying to open a socket to '" + host.getHost()
						+ "', using port " + host.getPort() + ".", 3);
				this.sock.connect(new InetSocketAddress(host.getHost(), host
						.getPort()), SOCKET_TIMEOUT);
			} catch (UnknownHostException uhe) {
				JHBServlet.dbg(
						"Failed to open a socket using the 'to' attribute", 3);
				throw uhe;
			} catch (IOException ioe) {
				JHBServlet.dbg(
						"Failed to open a socket using the 'to' attribute", 3);
				throw ioe;
			}
		}

		// at this point, we either have a socket, or an exception has already
		// been thrown.

		try {
			if (this.sock.isConnected())
				JHBServlet.dbg("Succesfully connected to " + to, 2);

			this.sock.setSoTimeout(SOCKET_TIMEOUT);
			// 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'"
					+ " version='1.0'" + ">");
			this.osw.flush();

			// create unique session id
			while (sessions.get(this.sid = createSessionID(24)) != null)
				;

			JHBServlet.dbg("creating session with id " + this.sid, 2);

			// register session
			sessions.put(this.sid, this);

			// create list of responses
			responses = new TreeMap();

			this.br = new BufferedReader(new InputStreamReader(this.sock
					.getInputStream(), "UTF-8"));

			this.streamPattern = Pattern.compile(
					".*<stream:stream[^>]*id=['|\"]([^'|^\"]+)['|\"][^>]*>.*",
					Pattern.DOTALL);

			this.stream10Pattern = Pattern
					.compile(
							".*<stream:stream[^>]*id=['|\"]([^'|^\"]+)['|\"][^>]*>.*(<stream.*)$",
							Pattern.DOTALL);

			this.stream10Test = Pattern.compile(
					".*<stream:stream[^>]*version=['|\"]1.0['|\"][^>]*>.*",
					Pattern.DOTALL);

			this.setStatus(SESS_ACTIVE);
		} catch (IOException ioe) {
			throw ioe;
		}
	}

整个构造方法的作用是创建一个新的 session 并且连接到 jabber 服务器上去。 Create a new session and connect to jabber server host denoted by <code> route </code> or <code> to </code> .

 

 

 

这是 Session 类的构造方法,带两个 String 类型的参数 toroute ,分别都表示与之建立会话的 Server ,而 route 是备用可选的: optional hostname of the server to connect to (might be null)

 

 

this . sock = new Socket();

this .setLastActive();

创建一个 Socket 对象,并且在此时 setLastActive ,因为他认为创建 Socket 对象算是 Active 动作吧。

// first, try connecting throught the 'route' attribute.

      if (route != null && !route.equals("")) {

        JHBServlet.dbg(

              "Trying to use 'route' attribute to open a socket...", 3);

        if (route.startsWith("xmpp:")) {

           route = route.substring("xmpp:".length());

        }

 

        int i;

        // has 'route' the optional port?

        if ((i = route.lastIndexOf(":")) != -1) {

           try {

              int p = Integer.parseInt(route.substring(i + 1));

              if (p >= 0 && p <= 65535) {

                 port = p;

                 JHBServlet.dbg(

                      "...route attribute holds a valid port ("

                            + port + ").", 3);

              }

           } catch (NumberFormatException nfe) {

           }

 

           route = route.substring(0, i);

        }

 

        JHBServlet.dbg("Trying to open a socket to '" + route

              + "', using port " + port + ".", 3);

 

        try {

           this.sock.connect(new InetSocketAddress(route, port),

                 SOCKET_TIMEOUT);

        } catch (Exception e) {

           JHBServlet.dbg(

                 "Failed to open a socket using the 'route' attribute",

                 3);

           /*

            * none of the exceptions possible should be reason to throw

            * anything. If the socket isn't opened, we'll get a retry using

            * the 'to' attribute anyway.

            */

        }

      }

接下来,试着用 route 来连接,结合下面的程序可以看出 route 的构成是这样的 xmpp:domain:port ,所以最终 socket 连接也是这样连的:

 

 

this.sock.connect(new InetSocketAddress(route, port),

                 SOCKET_TIMEOUT);

 

 

// If no socket has been opened, try connecting trough the 'to'

      // attribute.

      if (this.sock == null || !this.sock.isConnected()) {

        JHBServlet.dbg("Trying to use 'to' attribute to open a socket...",

              3);

        host = DNSUtil.resolveXMPPServerDomain(to, DEFAULT_XMPPPORT);

        try {

           JHBServlet.dbg("Trying to open a socket to '" + host.getHost()

                 + "', using port " + host.getPort() + ".", 3);

           this.sock.connect(new InetSocketAddress(host.getHost(), host

                 .getPort()), SOCKET_TIMEOUT);

        } catch (UnknownHostException uhe) {

           JHBServlet.dbg(

                 "Failed to open a socket using the 'to' attribute", 3);

           throw uhe;

        } catch (IOException ioe) {

           JHBServlet.dbg(

                 "Failed to open a socket using the 'to' attribute", 3);

           throw ioe;

        }

      }
 

 

 

接下来用 to 来连接,而对 to 的解析采用了封装的 resolveXMPPServerDomain 方法,得到的 DNSUtil.HostAddress 对象

 

// at this point, we either have a socket, or an exception // has already been thrown.

到此我们或者有了 socket 或者是一个已经抛出的 exception

 

 

if (this.sock.isConnected())

           JHBServlet.dbg("Succesfully connected to " + to, 2);

 

        this.sock.setSoTimeout(SOCKET_TIMEOUT);

        // 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'"

              + " version='1.0'" + ">");

        this.osw.flush();
 

 

首先向 OutputStreamWriter 流中写数据。

 

 

// create unique session id

        while (sessions.get(this.sid = createSessionID(24)) != null);
 

 

接着创建一个独特的 session id ,这里的 sessions 是一个 HashTable ,如果对应 key 所得不为 null ,即表重复,循取。

 

// register session

        sessions.put(this.sid, this);
 

 

取得 unique sid 之后,记得存入。接下去是一些 Pattern 对象的建立,最后:

this.setStatus(SESS_ACTIVE);
 

表明到此处 session 是处于活动状态的。 Sid 型如: terminating session WOfs8pYb5UEpttRISjjS1Uxc

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值