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[]) { |
จากนั้นก็ไปเรียก 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 บ้าง (หรือใครทราบก็ช่วยแนะนำด้วยนะครับ) 
เอาไว้แค่นี้ก่อนดีกว่า แล้วค่อยมาเขียนต่อนะครับ
สวัสดีครับ ผมตามเข้ามาอ่าน ได้ความรู้มากครับ