Simple Call Setup example

Simple Call Setup example (JAIN-SIP)

วันนี้ผมขออธิบายตัวอย่าง simplecallsetup (เฉพาะไฟล์ Shootme) ที่เป็น example ของ JAIN-SIP คร่าว ๆ นะครับ

ตัวอย่างนี้ มี 2 ไฟล์หลัก ๆ ก็คือ Shootme.java กับ Shootist.java มาเริ่มกันที่ Shootme.java กัน ไฟล์นี้ทำหน้าที่เปรียบเสมือนกับ SIP Server คอยรอรับ การเชื่อมต่อมาจาก SIP Client ซึ่งก็คือ Shootist.java นั่นเอง

แน่นอน ว่า java ก็ต้องเริ่มการทำงานจากฟังก์ชัน main

    public static void main(String args[]) {
        new Shootme().init();
    }

จากนั้นก็ไปเรียก method init() ซึ่งยาวพอสมควร

    public void init() {
           SipFactory sipFactory = null;
           sipStack = null;
           sipFactory = SipFactory.getInstance();
           sipFactory.setPathName("gov.nist");
            Properties properties = new Properties();
            properties.setProperty("javax.sip.STACK_NAME", "shootme");
            ....

            System.out.println("udp provider " + sipProvider);
            sipProvider.addSipListener(listener);
        }

กลไกการทำงานของ method init ก็สร้างพวก factory ทั้งหลายเพื่อที่จะได้มี instace มาจัดการกับ SIP message ต่าง ๆ ก่อนที่จะใช้ในการสร้าง session  ซึ่งก็จะเหมือนกับที่ผมเขียนไว้ในตอน JAIN SIP #2 ครับ ผมข้ามไปเลยละกัน

หลังจากจบ method ของ init ซึ่งจริง ๆ ก็ไม่จบจริง ๆ นะครับ ถ้าสังเกตให้ดีจะเห็นว่ามีคำสั่ง sipProvider.addSipListener(listener); อันนี้แหละที่เป็นตัว ทำให้ SIP Server (Shootme instance ) ของเรา รอรับ request ที่ร้องขอเข้ามาจาก Client (Shootme instance) หรือ SIP Client ตัวอื่น ๆ

เมื่อมีการร้องขอเข้ามา SIP Server ก็จะไปเรียก method processRequest

 public void processRequest(RequestEvent requestEvent) {
        Request request = requestEvent.getRequest();
        ServerTransaction serverTransactionId = requestEvent
                .getServerTransaction();

        System.out.println("\n\nRequest " + request.getMethod()
                + " received at " + sipStack.getStackName()
                + " with server transaction id " + serverTransactionId);

        if (request.getMethod().equals(Request.INVITE)) {
            processInvite(requestEvent, serverTransactionId);
        } else if (request.getMethod().equals(Request.ACK)) {
            processAck(requestEvent, serverTransactionId);
        } else if (request.getMethod().equals(Request.BYE)) {
            processBye(requestEvent, serverTransactionId);
        } else if (request.getMethod().equals(Request.CANCEL)) {
            processCancel(requestEvent, serverTransactionId);
        }
                      .....

อ่าน SIP Request จาก method requestEvent.getRequest();  โดยจะเปรียบเทียบว่า Request ที่เข้ามาเป็น SIP Message อะไร  ก็ให้ไปทำ method process นั้น ๆ ในตัวอย่างนี้ มีแค่ INVITE, ACK, BYE, CANCEL ถ้าเราอยากใช้กับ SIP Client ตัวอื่น ๆ เช่น X-Lite, Ekiga เราก็ต้อง เขียน method processRegister() เพิ่ม

ผมลองแก้เล่น ๆ เป็นแบบนี้ครับ

  เพิ่ม ใน method  processRequest(RequestEvent requestEvent)

        if (request.getMethod().equals(Request.REGISTER)) {
            processRegister(requestEvent, serverTransactionId);
        }

และเพิ่ม method นี้ครับ

   public void processRegister (RequestEvent requestEvent,
            ServerTransaction serverTransaction) {

        try {
            System.out.println("shootme: got an Register! ");
            System.out.println("Dialog State = " + dialog.getState());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
     }

  หลังจากนั้นผมทดลอง run shootme ดูอีกครั้ง และก็เปิดโปรแกรม X-Lite ก็เห็น message Register วิ่งผ่านในหน้า console ของ shootme แล้ว แสดงว่า SIP Server ตัวนี้รับ message จาก SIP Client จริง ๆ ได้ แต่ process นี้ก็ยังเอาไปใช้จริง ๆ ไม่ได้นะครับ เพราะ ผมแค่ให้มัน print ขอความแสดงเพื่อตรวจสอบเท่านั้น   แต่ในความเป็นจริง การ Register จะต้องลงทะเบียนกับ SIP Server ซึ่งผมคงต้องไปหาข้อมูลเพิ่มเติม ว่า JAIN-SIP มี API อะไรในการ Register user บ้าง (หรือใครทราบก็ช่วยแนะนำด้วยนะครับ) 



เอาไว้แค่นี้ก่อนดีกว่า แล้วค่อยมาเขียนต่อนะครับ