Sipdroid數據發送流程

馬上要睡覺了,今天弄了一整天算是對Sipdroid的框架有了個基本的瞭解,在睡覺之前整理一下Sipdroid的數據發送流程.

public class SipProvider implements Configurable, TransportListener

實現TransportListener的目的是什麼?簡單,爲了實現回調,SipProvider實現了TransportListener,記住-這個很重要.

數據發送對應的流程對應如下,再這裏假設message就是已經生成好了的(實際上的message涉及到很多的協議,搞了很長時候,這會還在犯暈)

SipdroidProvider----UdpTransport-UdpProvider-UdpSocket

UdpSocket擁有我們最直接的兩個方法:send  receive,方法原型如下:


  • /** Receives a datagram packet from this socket. */
  • public void receive(UdpPacket pkt) throws java.io.IOException {
  • DatagramPacket dgram = pkt.getDatagramPacket();
  • socket.receive(dgram);
  • pkt.setDatagramPacket(dgram);
  • }
  • /** Sends an UDP packet from this socket. */
  • public void send(UdpPacket pkt) throws java.io.IOException {
  • socket.send(pkt.getDatagramPacket());
  • }

複製代碼

UdpProvider擁有UdpSocket,依託UdpSocket來實現數據的收發,但是receive是阻塞的,這個大家詳細緣由看我的另一篇文章:
http://www.shouyanwang.org/thread-5-1-1.html

因此UdpProvider必然要繼承thread來讓自己成爲線程:


  • /** The main thread */
  • public void run() {
  • byte[] buf = new byte[BUFFER_SIZE];
  • UdpPacket packet = new UdpPacket(buf, buf.length);//UdpPacket是DataProgramPacket更深層次的一封裝
  • Exception error = null;
  • long expire = 0;
  • if (alive_time > 0)
  • expire = System.currentTimeMillis() + alive_time;
  • try {
  • // socket.setSoTimeout(socket_timeout); modified
  • // loop
  • while (!stop) {
  • try {
  • socket.receive(packet);
  • } catch (InterruptedIOException ie) {
  • if (alive_time > 0 && System.currentTimeMillis() > expire)
  • halt();
  • continue;
  • }
  • if (packet.getLength() >= minimum_length) {
  • if (listener != null)
  • listener.onReceivedPacket(this, packet);///嚴重注意這裏
  • if (alive_time > 0)
  • expire = System.currentTimeMillis() + alive_time;
  • }
  • packet = new UdpPacket(buf, buf.length);
  • }
  • } catch (Exception e) {
  • error = e;
  • stop = true;
  • }
  • is_running = false;
  • if (listener != null)
  • listener.onServiceTerminated(this, error);
  • listener = null;
  • }

複製代碼

UdpProvider中有一個UdpProviderListener,在UdpProvider進行初始化的時候便指定了

Siproid----UdpTransport-UdpProvider-UdpSocket(仔細看這個初始化的流程圖,我給出它們的構造函數)

public UdpProvider(UdpSocket socket, UdpProviderListener listener) //UdpProvider構造函數

public UdpTransport(int port, TransportListener listener)//UdpTransProt構造函數,UdpTransport實現了UdpProviderListener

udp = new UdpTransport(host_port, host_ipaddr, Sipdroid.this);


所以流程是怎麼樣的呢?
客戶端接收到服務器返回的數據後,首先是在UdpProvider的run裏面的,上面的紅色字體注意沒,UdpProvider會用UdpProviderListener進行回調,UdpProviderListener是誰呢,是UdpTransport,因爲UdpTransport實現了UdpProviderListener接口,並在自己的構造函數中將自己作爲參數傳遞給了UdpProvider.

好了,數據已經到了UdpTransport手裏了,看下面的UdpTransport是如何實現的?


/** When a new UDP datagram is received. */
public void onReceivedPacket(UdpProvider udp, UdpPacket packet) {
  Message msg = new Message(packet);
  msg.setRemoteAddress(packet.getIpAddress().toString());
  msg.setRemotePort(packet.getPort());
  msg.setTransport(PROTO_UDP);
  if (listener != null)
   listener.onReceivedMessage(this, msg);
}


UdpTransport同樣只需要調用onReceivedMessage就可以將數據傳回給SipProvider呢,這樣SipProvider便獲得了從服務器返回的信息,然後程序在獲得信息後要做的就是對Message解析,並進行適配,確定手機客戶端這邊怎麼來響應。


通俗點說是上級將接口傳遞給下級,下級在獲得數據後便通過該接口將數據返回給上級.

轉自http://www.shouyanwang.org/thread-5-1-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章