📄 multicastrouter.java
字号:
// Remote server has a multicast service so send pending packets to the // multicast service for (Packet packet : packets) { Element addresses = getAddresses(packet); for (Iterator it=addresses.elementIterator("address");it.hasNext();) { Element address = (Element) it.next(); String jid = address.attributeValue("jid"); if (!jid.contains("@"+domain)) { if (Type.bcc.toString().equals(address.attributeValue("type"))) { it.remove(); } else { address.addAttribute("delivered", "true"); } } } // Set that the target of the packet is the multicast service packet.setTo(multicastService); // Send the packet to the remote entity packetRouter.route(packet); } } else { // Remote server does not have a multicast service so send pending packets // to each address for (Packet packet : packets) { Element addresses = getAddresses(packet); List<String> targets = new ArrayList<String>(); for (Iterator it=addresses.elementIterator("address");it.hasNext();) { Element address = (Element) it.next(); String jid = address.attributeValue("jid"); // Keep a list of the remote users that are going to receive the packet if (jid.contains("@"+domain)) { targets.add(jid); } // Set as delivered address.addAttribute("delivered", "true"); // Remove bcc addresses if (Type.bcc.toString().equals(address.attributeValue("type"))) { it.remove(); } } // Send the packet to each remote user for (String jid : targets) { packet.setTo(jid); packetRouter.route(packet); } } } } public void receivedAnswer(IQ packet) { // Look for the root node being discovered String domain = packet.getFrom().toString(); boolean isRoot = true; if (!nodes.containsKey(domain)) { domain = roots.get(domain); isRoot = false; } // Check if this is a disco#info response if ("http://jabber.org/protocol/disco#info" .equals(packet.getChildElement().getNamespaceURI())) { // Check if the node supports JEP-33 boolean supports = false; for (Iterator it = packet.getChildElement().elementIterator("feature"); it.hasNext();) { if (NAMESPACE.equals(((Element)it.next()).attributeValue("var"))) { supports = true; break; } } if (supports) { // JEP-33 is supported by the entity Collection<String> items = nodes.remove(domain); for (String item : items) { roots.remove(item); } String multicastService = packet.getFrom().toString(); cache.put(domain, multicastService); sendToRemoteServer(domain, multicastService); } else { if (isRoot && IQ.Type.error != packet.getType()) { // Discover node items with the hope that a sub-item supports JEP-33 IQ iq = new IQ(IQ.Type.get); iq.setFrom(server.getServerInfo().getName()); iq.setTo(packet.getFrom()); iq.setChildElement("query", "http://jabber.org/protocol/disco#items"); // Send the disco#items request to the remote server or component. The reply will be // processed by the IQResultListener (interface that this class implements) iqRouter.addIQResultListener(iq.getID(), this); iqRouter.route(iq); } else if (!isRoot) { // Process the disco#info response of an item that does not support JEP-33 roots.remove(packet.getFrom().toString()); Collection<String> items = nodes.get(domain); if (items != null) { items.remove(packet.getFrom().toString()); if (items.isEmpty()) { nodes.remove(domain); cache.put(domain, ""); sendToRemoteServer(domain, ""); } } } else { // Root domain does not support disco#info nodes.remove(domain); cache.put(domain, ""); sendToRemoteServer(domain, ""); } } } else { // This is a disco#items response Collection<Element> items = packet.getChildElement().elements("item"); if (IQ.Type.error == packet.getType() || items.isEmpty()) { // Root domain does not support disco#items nodes.remove(domain); cache.put(domain, ""); sendToRemoteServer(domain, ""); } else { // Keep the list of items found in the requested domain List<String> jids = new ArrayList<String>(); for (Element item : items) { String jid = item.attributeValue("jid"); jids.add(jid); // Add that this item was found for the following domain roots.put(jid, domain); } nodes.put(domain, new CopyOnWriteArrayList<String>(jids)); // Send disco#info to each discovered item for (Element item : items) { // Discover if remote server supports JEP-33 (Extended Stanza Addressing) IQ iq = new IQ(IQ.Type.get); iq.setFrom(server.getServerInfo().getName()); iq.setTo(item.attributeValue("jid")); Element child = iq.setChildElement("query", "http://jabber.org/protocol/disco#info"); if (item.attributeValue("node") != null) { child.addAttribute("node", item.attributeValue("node")); } // Send the disco#info request to the discovered item. The reply will be // processed by the IQResultListener (interface that this class implements) iqRouter.addIQResultListener(iq.getID(), this); iqRouter.route(iq); } } } } public Iterator<String> getFeatures() { ArrayList<String> features = new ArrayList<String>(); features.add(NAMESPACE); return features.iterator(); } public void initialize(XMPPServer server) { super.initialize(server); this.server = server; this.packetRouter = server.getPacketRouter(); this.iqRouter = server.getIQRouter(); } /** * Enumarion of the possible semantics of a particular address. */ private enum Type { /** * These addressees should receive 'blind carbon copies' of the stanza. This means that * the server MUST remove these addresses before the stanza is delivered to anyone other * than the given bcc addressee or the multicast service of the bcc addressee. */ bcc, /** * These addressees are the secondary recipients of the stanza. */ cc, /** * This address type contains no actual address information. Instead, it means that the * receiver SHOULD NOT reply to the message. This is useful when broadcasting messages * to many receivers. */ noreply, /** * This is the JID of a Multi-User Chat room to which responses should be sent. When a * user wants to reply to this stanza, the client SHOULD join this room first. Clients * SHOULD respect this request unless an explicit override occurs. There MAY be more than * one replyto or replyroom on a stanza, in which case the reply stanza MUST be routed * to all of the addresses. */ replyroom, /** * This is the address to which all replies are requested to be sent. Clients SHOULD * respect this request unless an explicit override occurs. There MAY be more than one * replyto or replyroom on a stanza, in which case the reply stanza MUST be routed to all * of the addresses. */ replyto, /** * These addressees are the primary recipients of the stanza. */ to; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -