- @Override
- public void process(Packet packet, XMPPResourceConnection session,
- NonAuthUserRepository repo, Queue<Packet> results, Map<String, Object> settings) throws XMPPException {
- // For performance reasons it is better to do the check
- // before calling logging method.
- if (log.isLoggable(Level.FINEST)) {
- log.log(Level.FINEST, "Processing packet: {0}, for session: {1}", new Object[] {
- packet,
- session });
- }
- // You may want to skip processing completely if the user is offline.
- if (session == null) {
- processOfflineUser( packet, results );
- return;
- } // end of if (session == null)
- try {
- // Remember to cut the resource part off before comparing JIDs
- BareJID id = (packet.getStanzaTo() != null)
- ? packet.getStanzaTo().getBareJID()
- : null;
- // Checking if this is a packet TO the owner of the session
- if (session.isUserId(id)) {
- if (log.isLoggable(Level.FINEST)) {
- log.log(Level.FINEST, "Message 'to' this user, packet: {0}, for session: {1}",
- new Object[] { packet,
- session });
- }
- if (packet.getStanzaFrom() != null && session.isUserId(packet.getStanzaFrom().getBareJID())) {
- JID connectionId = session.getConnectionId();
- if (connectionId.equals(packet.getPacketFrom())) {
- results.offer(packet.copyElementOnly());
- // this would cause message packet to be stored in offline storage and will not
- // send recipient-unavailable error but it will behave the same as a message to
- // unavailable resources from other sessions or servers
- return;
- }
- }
- // Yes this is message to 'this' client
- List<XMPPResourceConnection> conns = new ArrayList<XMPPResourceConnection>(5);
- // This is where and how we set the address of the component
- // which should rceive the result packet for the final delivery
- // to the end-user. In most cases this is a c2s or Bosh component
- // which keep the user connection.
- String resource = packet.getStanzaTo().getResource();
- if (resource == null) {
- // If the message is sent to BareJID then the message is delivered to
- // all resources
- conns.addAll(getConnectionsForMessageDelivery(session));
- } else {
- // Otherwise only to the given resource or sent back as error.
- XMPPResourceConnection con = session.getParentSession().getResourceForResource(
- resource);
- if (con != null) {
- conns.add(con);
- }
- }
- // MessageCarbons: message cloned to all resources? why? it should be copied only
- // to resources with non negative priority!!
-
- if (conns.size() > 0) {
- for (XMPPResourceConnection con : conns) {
- Packet result = packet.copyElementOnly();
- result.setPacketTo(con.getConnectionId());
- // In most cases this might be skept, however if there is a
- // problem during packet delivery an error might be sent back
- result.setPacketFrom(packet.getTo());
- // Don't forget to add the packet to the results queue or it
- // will be lost.
- results.offer(result);
- if (log.isLoggable(Level.FINEST)) {
- log.log(Level.FINEST, "Delivering message, packet: {0}, to session: {1}",
- new Object[] { packet,
- con });
- }
- }
- } else {
- // if there are no user connections we should process packet
- // the same as with missing session (i.e. should be stored if
- // has type 'chat'
- processOfflineUser( packet, results );
- }
- return;
- } // end of else
- // Remember to cut the resource part off before comparing JIDs
- id = (packet.getStanzaFrom() != null)
- ? packet.getStanzaFrom().getBareJID()
- : null;
- // Checking if this is maybe packet FROM the client
- if (session.isUserId(id)) {
- // This is a packet FROM this client, the simplest action is
- // to forward it to is't destination:
- // Simple clone the XML element and....
- // ... putting it to results queue is enough
- results.offer(packet.copyElementOnly());
- return;
- }
- // Can we really reach this place here?
- // Yes, some packets don't even have from or to address.
- // The best example is IQ packet which is usually a request to
- // the server for some data. Such packets may not have any addresses
- // And they usually require more complex processing
- // This is how you check whether this is a packet FROM the user
- // who is owner of the session:
- JID jid = packet.getFrom();
- // This test is in most cases equal to checking getElemFrom()
- if (session.getConnectionId().equals(jid)) {
- // Do some packet specific processing here, but we are dealing
- // with messages here which normally need just forwarding
- Element el_result = packet.getElement().clone();
- // If we are here it means FROM address was missing from the
- // packet, it is a place to set it here:
- el_result.setAttribute("from", session.getJID().toString());
- Packet result = Packet.packetInstance(el_result, session.getJID(), packet
- .getStanzaTo());
- // ... putting it to results queue is enough
- results.offer(result);
- }
- } catch (NotAuthorizedException e) {
- log.log(Level.FINE, "NotAuthorizedException for packet: " + packet + " for session: " + session, e);
- results.offer(Authorization.NOT_AUTHORIZED.getResponseMessage(packet,
- "You must authorize session first.", true));
- } // end of try-catch
- }
检查stanzaTo与session匹配通过后,根据session拿到接收方所有的连接(可能多端登陆),然后Packet result = packet.copyElementOnly()生成新的packet(原packet丢弃了),并将packetTo设置为接收方连接的ConnectionId(例如:c2s@llooper/192.168.0.33_5222_192.168.0.33_38624),通过addOutPacket()方法塞到out_queue队列。
此时packet:packetFrom = sess-man@llooper,packetTo =c2s@llooper/192.168.0.33_5222_192.168.0.33_38624。