Emitter類
Emitter類可以說(shuō)是socket.io-client 中極其的類,Socket.class 便繼承自該類.
先看看Emitter類中定義的變量callbacks:
private ConcurrentMap<String, ConcurrentLinkedQueue<Listener>> callbacks = new ConcurrentHashMap<String, ConcurrentLinkedQueue<Listener>>();
可以說(shuō)整個(gè)Emitter類就是圍繞著callbacks在進(jìn)行操作御蒲,callbacks通過(guò)將事件名-回調(diào)接口保存在map類型的數(shù)據(jù)結(jié)構(gòu)中,以便在事件發(fā)生時(shí)觸發(fā)相應(yīng)的回調(diào)接口通知監(jiān)聽(tīng)者平委。
ConcurrentMap 和 ConcurrentLinkedQueue 都是線程安全的
Emitter類中定義的監(jiān)聽(tīng)接口 Listener:
public static interface Listener {
public void call(Object... args);
}
外部監(jiān)聽(tīng)者通過(guò)該接口監(jiān)聽(tīng)Emitter的事件觸發(fā),同時(shí)另外一個(gè)一次性的接口OnceListener繼承自這一接口夺谁。
看看Emitter類中最重要的幾個(gè)方法:
public Emitter on(String event, Listener fn)
public Emitter off()
public Emitter off(String event)
public Emitter off(String event, Listener fn)
這三個(gè)方法顧名思義廉赔,都是解除事件監(jiān)聽(tīng)器。區(qū)別在于匾鸥,
第一個(gè)方法: 為callbacks解除所有事件的所有監(jiān)聽(tīng)器蜡塌。
第二個(gè)方法: 為所傳入的event事件解除該事件所有的監(jiān)聽(tīng)器。
第三個(gè)方法: 解除所傳入event事件的fn監(jiān)聽(tīng)器勿负。
三個(gè)方法各有各的使用范圍岗照。
public Emitter emit(String event, Object... args)
Emitter 通過(guò)調(diào)用該方法觸發(fā)事件,回調(diào)所有的監(jiān)聽(tīng)接口笆环,同時(shí)為每一個(gè)監(jiān)聽(tīng)接口傳入變量args. 使得每一個(gè)監(jiān)聽(tīng)接口都能夠操作相應(yīng)事件所攜帶的數(shù)據(jù)args.
Socket類
說(shuō)完Emitter類,便該說(shuō)說(shuō)Emitter類的子類Socket類了厚者,Socket類是 Socket.io 的Client類躁劣,負(fù)責(zé)管理Socket.io 通信過(guò)程中的一些細(xì)節(jié)操作。
進(jìn)入Socket先看看定義的一些事件常量和變量库菲,這里的事件常量不是我們用于傳輸數(shù)據(jù)的自定義事件账忘,而是Socket.io 同服務(wù)器鏈接過(guò)程中的各種事件。
其中有幾個(gè)變量需要注意一下熙宇,
private String nsp;
該Socket所鏈接到的命名空間.
private Map<Integer, Ack> acks = new HashMap<Integer, Ack>();
acks 通過(guò)Map容器裝載了一個(gè)標(biāo)識(shí)符(是一個(gè)回調(diào)接口)鳖擒,在之后服務(wù)器廣播相應(yīng)的事件之后會(huì)回調(diào)該接口,同ids相對(duì)應(yīng)烫止。
private final Queue<List<Object>> receiveBuffer = new LinkedList<List<Object>>();
receiveBuffer 緩存隊(duì)列裝載了收到從服務(wù)器發(fā)過(guò)來(lái)卻未處理的事件信息(不能夠立即處理而放在緩沖區(qū)的)蒋荚。
private final Queue<Packet<JSONArray>> sendBuffer = new LinkedList<Packet<JSONArray>>();
sendBuffer 緩存隊(duì)列裝載了將要發(fā)送到服務(wù)器的的事件信息(緩沖區(qū)的,不是立即發(fā)送的)馆蠕。
為什么要使用隊(duì)列期升,當(dāng)然是因?yàn)橐狥IFO啦!
來(lái)看看其中一些比較重要的方法:
public Emitter emit(final String event, final Object... args)
public Emitter emit(final String event, final Object[] args, final Ack ack)
這兩個(gè)方法非常重要互躬,Client就是從這里開(kāi)始觸發(fā)事件播赁,向服務(wù)器提交事件信息的。區(qū)別在于第二個(gè)方法傳入了一個(gè)回調(diào)接口Ack, emit()方法的調(diào)用者可以通過(guò)傳入一個(gè)實(shí)現(xiàn)了Ack接口的回調(diào)函數(shù)來(lái)對(duì)數(shù)據(jù)傳輸之后的結(jié)果進(jìn)行處理吼渡。
private void onpacket(Packet<?> packet)
對(duì)不同的Packet類型進(jìn)行轉(zhuǎn)發(fā)容为。
private void onevent(Packet<JSONArray> packet)
對(duì)從服務(wù)器返回的數(shù)據(jù)包進(jìn)行處理。
private void onack(Packet<JSONArray> packet)
接收到從服務(wù)器傳過(guò)來(lái)的數(shù)據(jù)包之后對(duì)Ack接口進(jìn)行回調(diào)。
private void emitBuffered()
將receiveBuffer, sendBuffer緩存區(qū)中的數(shù)據(jù)全部推到服務(wù)器端并清空緩存區(qū)坎背。