之前做即时通讯,扒了smack源码来参考。说下其中解包后进行通知的机制。
Filter类:accept(Packet packet)函数,传入packet在此函数中进行对比判断,返回true
则通过此filter认证。实现PacketFilter接口即可。
public interface PacketFilter {/**
* Tests whether or not the specified packet should pass the filter.
*
* @param packet the packet to test.
* @return true if and only if <tt>packet</tt> passes the filter.
*/
public boolean accept(Packet packet);
}
ListenerWrapper类:packetListener对应了自己在应用中定义的Listener(实现PacketListener接口),当通过对应的packetFilter之后,则进行回掉;
/**
* A wrapper class to associate a packet filter with a listener.
*/
protected static class ListenerWrapper {private PacketListener packetListener;
private PacketFilter packetFilter;/**
* Create a class which associates a packet filter with a listener.
*
* @param packetListener the packet listener.
* @param packetFilter the associated filter or null if it listen for all packets.
*/
public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) {
this.packetListener = packetListener;
this.packetFilter = packetFilter;
}/**
* Notify and process the packet listener if the filter matches the packet.
*
* @param packet the packet which was sent or received.
*/
public void notifyListener(Packet packet) {
if (packetFilter == null || packetFilter.accept(packet)) {
packetListener.processPacket(packet);
}
}
}
public interface PacketListener {/**
* Process the next packet sent to this packet listener.<p>
*
* A single thread is responsible for invoking all listeners, so
* it‘s very important that implementations of this method not block
* for any extended period of time.
*
* @param packet the packet to process.
*/
public void processPacket(Packet packet);}
接下来就是分包了,PacketReader中listenerExecutor.submit(new
ListenerNotification(packet));在ListenerNotification线程里面进行判断,关键代码如下,写在run里面
for (ListenerWrapper listenerWrapper : connection.recvListeners.values()) {
listenerWrapper.notifyListener(packet);
}
通过迭代出ListenerWrapper调用notifyListener函数,查找通过验证的filter然后相对应是哪个listener就进行通知。
smack 监听不同packet机制,布布扣,bubuko.com