程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> 巧用Java 實現個性MSN聊天功能

巧用Java 實現個性MSN聊天功能

編輯:關於JSP

巧用Java 實現個性MSN聊天功能

MSN Messenger這一由世界頭號軟件商-微軟公司開發的即時通訊軟件,憑借其與windows操作系統和整個微軟產品家族的緊密結合,簡單實用、性能穩定、世界通用等特點,很快被中國用戶接受,目前其用戶正在以幾何數字增長。但是讓開發者雀躍的是該軟件同時也提供了開放的API以及開放的通訊協議。

著名的MSN Plus就是一款利用其API開發的用於擴展MSN Messenger功能的插件。而我們今天要介紹的jMSN則是封裝了MSN Messenger開放的通訊協議的JAVA API,通過這個API開發者完全可以使用JAVA語言模擬出MSN Messenger軟件,API的作者也提供一個用JAVA語言編寫的在某方面功能甚至比MSN Messenger還強大的MSN 客戶端軟件。

由於采用了跨平台的JAVA語言開發,因此該軟件也可同時運行於其他操作系統,目前已經經過測試的有各種Linux系統以及Mac OS上,當然還有視窗操作系統。

jMSN是一個韓國人開發的開放源碼的API,可以從http://sourceforge.net/projects/jmsn/站點上下載,該項目的首頁基本上以韓文為主,包括它的API文檔的說明都是韓文。這個讓我非常頭疼,不過沒有關系,因為jMSN非常簡單,如果沒有什麼特殊情況下不看那些說明也沒有關系。

jMSN的主頁中提供兩個部件供下載如下圖所示,其中jmsn是一個完整的JAVA應用程序,下載解壓後可以直接運行,運行的界面跟微軟的MSN Messenger很類似,包括操作上都非常一致,如果你的操作系統是Linux或者其他那都可以直接用它來替代微軟的程序。另外一個是msnm-lib,這個就是我們今天要介紹的API,它僅僅是一個開發包,在jmsn組件中已經包含了這個包。

 

你可能想先體驗一下jmsn自帶的程序看看到底能完成什麼樣的功能吧?解壓jmsn壓縮包後的目錄中會有一個可執行文件,不過如果你的JDK不是使用安裝程序安裝的,建議你不用執行它,它會找不到jre的。

你可以使用命令行來啟動這個程序,這樣做有個好處是你還可以看到運行中打印出來的信息。

啟動jMSN的命令:

 

java -jar jmsn.jar

 

jMSN的登錄界面以及主窗口如下圖所示:

 

 

應該說這個界面跟MSN Messenger是非常類似的。用戶可以通過它發送和接收消息等。在啟動jMSN的命令行窗口中可以看到jMSN與服務器之間通訊的詳細信息。

前面我們主要在介紹j MSN大概的情況,介紹它能完成什麼樣的功能。

下面我們開始來了解怎麼利用jMSN自帶的API:

msnm-lib來實現這些功能。

下圖是msnm-lib與jMSN包括MSN系統之間的關系,也就是說我們可以通過msnm-lib來完成與MSN服務器之間的通訊而不需要我們去操心具體的通訊協議的細節。事實上msnm-lib給我們做了更多的事情使得我們使用msnm-lib來開發一個MSN應用程序變得非常的簡單,這也就是我前面提到的我們完全可以不去可能它所提供的韓文API文檔的緣故,因為使用它實在是太簡單了。

 

  
 
閩南語說:說破不值錢!閒話說了那麼多,現在我們就開始來開發我們自己基於JAVA的跨平台的MSN客戶端程序。相信聽到這句大家都會覺得血脈膨脹,沒錯,還有什麼比動手寫程序更讓人興奮的事情呢?何況還是基於JAVA的、跨平台的!
我們先給出一段可運行的代碼來完成一個最簡單的功能:當有人把它加入好友時,程序自動將之加入好友,當有人給它發送信息,程序自動回復一條相同的信息。OK,完成這麼簡單的功能的代碼如下:
 
/*

* Created on 2003-11-21 by Liudong

*/

package jmsn.demo; 

import rath.msnm.MSNMessenger;

import rath.msnm.SwitchboardSession;

import rath.msnm.UserStatus;

import rath.msnm.entity.MsnFriend;

import rath.msnm.event.MsnAdapter;

import rath.msnm.msg.MimeMessage;

/**

* MSN演示程序

* @author Liudong

*/

public class MSNDaemon extends Thread {

private static MSNMessenger msn;

public static void main(String[] args) {

msn = new MSNMessenger("[email protected]", "password");

msn.setInitialStatus(UserStatus.ONLINE);

msn.addMsnListener(new MSNAdapter(msn));

msn.login();

System.out.println("Waiting for the response....");

//捕捉Ctrl+C的輸入以便注銷MSN的登錄

Runtime.getRuntime().addShutdownHook(new MSNDaemon());

}

/**

* 用戶中止程序執行

*/

public void run() {

msn.logout();

System.out.println("MSN Logout OK");

}

}

/**

* MSN消息事件處理類

* @author Liudong

*/

 
class MSNAdapter extends MsnAdapter {

 MSNMessenger messenger;

public MSNAdapter(MSNMessenger messenger) {

this.messenger = messenger;

}

/**

* 某人正在輸入信息

*/

public void progressTyping(

SwitchboardSession ss,

MsnFriend friend,

String typingUser) {

System.out.println(

friend.getLoginName() + "正在輸入信息...");

}

/**

* 收到消息的時候執行該方法

*/

public void instantMessageReceived(

SwitchboardSession ss,

MsnFriend friend,

MimeMessage mime) {

System.out.print(

"接收到消息:" + friend.getFriendlyName() + "->");

System.out.println(mime.getMessage());

try {

//發送相同的回復信息給發送者messenger.sendMessage(

friend.getLoginName(), mime);

} 

catch (Exception e) {

e.printStackTrace();

}

}

/**

* 登錄成功後執行該方法

*/

public void loginComplete(MsnFriend own) {

System.out.println(

own.getLoginName() + " Login OK");

}

/**

* 登錄失敗後執行該方法

*/

public void loginError(

String header) {

System.out.println(

"Login Failed: " + header);

}

/**

* 好友離線時執行該方法

*/

public void userOffline(String loginName) {

System.out.println("USER " + loginName + " Logout.");

}

/**

* 好友上線時執行該方法

*/

public void userOnline(MsnFriend friend) {

System.out.println(

"USER "+friend.getFriendlyName()+" Login.");

}

/**

* 有人加我為好友時執行

*/

public void whoAddedMe(MsnFriend friend) {

System.out.println(

"USER " + friend.getLoginName() + " Addme.");

try {

messenger.addFriend(friend.getLoginName());

}

 catch (Exception e) {

e.printStackTrace();

}

}

 
/**

* 有人把我從好友列表中刪除時執行

*/

public void whoRemovedMe(MsnFriend friend) {

System.out.println("USER "+friend.getLoginName()+" Remove me.");

try {

messenger.removeFriend(friend.getLoginName());

}

 catch (Exception e) {

e.printStackTrace();

}

}

}

除了兩個常用的對象MsnFriend以及MimeMessage分別用來表示我的好友以及MSN信息外,其他我們需要了解的也就是MSNMessenger以及MsnAdapter了。當然了前提是我們不需要除了聊天外的其他功能,例如文件傳輸等等。類MSNMessenger 對應著一個帳號的一次登錄會話。
我們僅僅是需要告訴MSNMessenger類我們登錄所用的帳號、密碼、登錄後的初始狀態以及我們怎麼來處理從MSN服務器上接收到的任何信息。在msnm-lib中,處理MSN信息是通過一個叫MsnAdapter類來處理的,這個類定義了如何處理例如收到消息、有人加我為好友等等的事件,開發者可以重載這些方法以便進行自行處理何況還是基於JAVA的、跨平台的!
我們先給出一段可運行的代碼來完成一個最簡單的功能:當有人把它加入好友時,程序自動將之加入好友,當有人給它發送信息,程序自動回復一條相同的信息。OK,完成這麼簡單的功能的代碼如下:
 
/*

* Created on 2003-11-21 by Liudong

*/

package jmsn.demo; 

import rath.msnm.MSNMessenger;

import rath.msnm.SwitchboardSession;

import rath.msnm.UserStatus;

import rath.msnm.entity.MsnFriend;

import rath.msnm.event.MsnAdapter;

import rath.msnm.msg.MimeMessage;

/**

* MSN演示程序

* @author Liudong

*/

public class MSNDaemon extends Thread {

private static MSNMessenger msn;

public static void main(String[] args) {

msn = new MSNMessenger("[email protected]", "password");

msn.setInitialStatus(UserStatus.ONLINE);

msn.addMsnListener(new MSNAdapter(msn));

msn.login();

System.out.println("Waiting for the response....");

//捕捉Ctrl+C的輸入以便注銷MSN的登錄

Runtime.getRuntime().addShutdownHook(new MSNDaemon());

}

/**

* 用戶中止程序執行

*/

public void run() {

msn.logout();

System.out.println("MSN Logout OK");

}

}

/**

* MSN消息事件處理類

* @author Liudong

*/

 
class MSNAdapter extends MsnAdapter {

 MSNMessenger messenger;

public MSNAdapter(MSNMessenger messenger) {

this.messenger = messenger;

}

/**

* 某人正在輸入信息

*/

public void progressTyping(

SwitchboardSession ss,

MsnFriend friend,

String typingUser) {

System.out.println(

friend.getLoginName() + "正在輸入信息...");

}

/**

* 收到消息的時候執行該方法

*/

public void instantMessageReceived(

SwitchboardSession ss,

MsnFriend friend,

MimeMessage mime) {

System.out.print(

"接收到消息:" + friend.getFriendlyName() + "->");

System.out.println(mime.getMessage());

try {

//發送相同的回復信息給發送者messenger.sendMessage(

friend.getLoginName(), mime);

} 

catch (Exception e) {

e.printStackTrace();

}

}

/**

* 登錄成功後執行該方法

*/

public void loginComplete(MsnFriend own) {

System.out.println(

own.getLoginName() + " Login OK");

}

/**

* 登錄失敗後執行該方法

*/

public void loginError(

String header) {

System.out.println(

"Login Failed: " + header);

}

/**

* 好友離線時執行該方法

*/

public void userOffline(String loginName) {

System.out.println("USER " + loginName + " Logout.");

}

/**

* 好友上線時執行該方法

*/

public void userOnline(MsnFriend friend) {

System.out.println(

"USER "+friend.getFriendlyName()+" Login.");

}

/**

* 有人加我為好友時執行

*/

public void whoAddedMe(MsnFriend friend) {

System.out.println(

"USER " + friend.getLoginName() + " Addme.");

try {

messenger.addFriend(friend.getLoginName());

}

 catch (Exception e) {

e.printStackTrace();

}

}
* 有人把我從好友列表中刪除時執行

*/

public void whoRemovedMe(MsnFriend friend) {

System.out.println("USER "+friend.getLoginName()+" Remove me.");

try {

messenger.removeFriend(friend.getLoginName());

}

catch (Exception e) {

e.printStackTrace();

}

}

}

除了兩個常用的對象MsnFriend以及MimeMessage分別用來表示我的好友以及MSN信息外,其他我們需要了解的也就是MSNMessenger以及MsnAdapter了。當然了前提是我們不需要除了聊天外的其他功能,例如文件傳輸等等。類MSNMessenger 對應著一個帳號的一次登錄會話。
我們僅僅是需要告訴MSNMessenger類我們登錄所用的帳號、密碼、登錄後的初始狀態以及我們怎麼來處理從MSN服務器上接收到的任何信息。在msnm-lib中,處理MSN信息是通過一個叫MsnAdapter類來處理的,這個類定義了如何處理例如收到消息、有人加我為好友等等的事件,開發者可以重載這些方法以便進行自行處理。
  

 

我們自行擴展MsnAdapter的類必須告訴MSNMessenger實例知道,這也就是我們前面代碼中的msn.addMsnListener(new MSNAdapter(msn)); 自行擴展MsnAdapter的類是用來處理被動消息的,例如有人給我發消息等。當我們要發送消息給別人的時候就需要用到MSNMessenger的實例,這也就是我們為什麼要把MSNMessenger的實例傳遞給MSNAdapter的原因,因為當我們接收到任何消息時要給發送人回復一條相同的信息。

到此我們前面提出的簡單功能已經完成了,讀者可以在自己的機器上進行測試,運行時需要用到msnm-lib庫,也就是msnm.jar文件。下圖是運行時候的一個截圖:

 

關於多人聊天

MSN有另外一個不錯的功能就是多人同時聊天,msnm-lib對這個功能支持也非常好。在MsnAdapter中定義的方法instantMessageReceived的第一個參數類型為SwitchboardSession。當接收到消息時,我們可以從這個參數中獲取多人聊天的一個會話標識,同時可以通過getMsnFriends來讀取參與當前聊天的所有好友。當你要主動發送消息的時候你就必須從SwitchboardSession中讀取所有的好友並給他們一一發送信息。

關於文件傳輸

可能這是我發現的關於msnm-lib的唯一不足,或者說還不夠完善的部分。經過測試發現使用微軟的MSN程序可以正常傳輸文件的兩台機器用jMSN卻無法傳輸,錯誤信息都是說連接超時,這兩台機器不在同一個子網。相信msnm-lib對這個功能並沒有進行處理。由於並沒有兩台直接連接Internet的機器,因此關於jMSN的文件傳輸一直都沒有辦法來做一個試驗,希望新版本的msnm-lib能解決好這個問題。

總結

盡管在文件傳輸上有點瑕疵,但是msnm-lib所提供的功能已經非常棒了,至少在我第一眼看到它的時候心裡說:沒錯,這就是我想要的東西!本文旨在介紹如何使用msnm-lib來完成一個簡單的MSN客戶端,至於如果讓它在實際的應用系統中發揮作用,讀者們肯定有比我更多的想法,比如說是否可以利用它來豐富客服的渠道等等,當然這些都超過我們的題目。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved