使用 IBM Lotus Sametime Java 工具包建立股票報價機器人

genusBIT發表於2008-07-21

將展示如何使用 IBM Lotus Sametime Java 工具包來建立檢索 IBM Lotus Sametime Connect 股票資訊的機器人。StockBot 使用 Web 服務來檢索 Yahoo! Finance Web 站點的股票報價資訊。

developerWorks Lotus 文章 “建立自己的 Sametime Bots, 第 1 部分” 闡述瞭如何建立 IBM Lotus Sametime 機器人,使用 Magic Eightball 例子來協助討論。隨著上述文章的發表及 IBM Lotus Sametime V7.5 的問世,Lotus Sametime 工具包進行了顯著的重新包裝。本文將討論那些包裝更改並通過建立提供股票報價資訊的機器人來重新討論機器人方面的內容。該股票報價資訊是通過 IBM Rational Application Developer V6.0 所建立的 Web 服務獲取的。

儘管我們重述了一些有關機器人的資訊,但並未給出詳盡講解。我們建議您閱讀 參考資料 中的文章來熟悉機器人這個主題。同樣,如果您不熟悉 Web 服務,也可以重溫 developerWorks New to SOA and Web Services 頁面 上的資料。

Sametime 機器人和 IBM Lotus Sametime Java 工具包

術語機器人(bot)源自 robot 這個詞,表示從使用者獲取指令並提供響應的軟體應用程式。Sametime 機器人是一種利用了 Lotus Sametime 的到場提醒和即時訊息傳遞功能的機器人。

對於 IBM Lotus Sametime Connect 來說,Sametime 機器人是作為 Contacts 列表中的線上聯絡人出現的。圖 1 展示了 Lotus Sametime Connect 與 StockBot 的互動預覽,它是本文所構建的機器人。


圖 1. StockBot 預覽
StockBot 預覽

可以訓練機器人,使之執行諸如向使用者提供隨需應變資訊之類的操作,但是如何訓練機器人呢?可以使用 IBM Lotus Sametime Java 工具包以程式設計方式實現。

Lotus Sametime Java 工具包用於桌面和伺服器開發。它允許您向 Java 應用程式新增 Lotus Sametime 特性。隨 IBM Lotus Sametime Software Development Kit (SDK) 提供的工具包指南將 Lotus Sametime Java Toolkit 描述為:“開發人員用於構建應用程式(這些應用程式使用了由 Lotus Sametime 提供的功能和服務)的構件塊和元件的集合”。

從 Lotus Sametime V7.5 開始,將所有 Lotus Sametime 客戶機和伺服器工具包都捆綁到名為 Lotus Sametime SDK 的統一包中。可以從 developerworks Lotus Toolkits 頁面 下載 SDK。

使用 IBM Rational Application Developer 進行開發

可以在支援 Java Development Kit 1.4.2 或 1.5 的任何 Java 開發環境中使用 Lotus Sametime 工具包。對於我們的機器人開發來說,將使用 IBM Rational Application Developer V6。Rational Application Developer 是一個基於(可加快開發速度的)Eclipse 平臺的功能強大的整合開發環境(integrated development environment,IDE)。

因為本文並不是關於 Rational Application Developer 的教程,所以假定您熟悉如何使用該開發環境。如果不熟悉的話,我們建議您檢視 developerWorks Rational Application Developer for WebSphere Software 頁面。Rational Application Developer 隨附了內建的 IBM WebSphere Application Server V6 測試環境,在開發期間可以使用它來增強企業應用程式。

使用 IBM Lotus Sametime 7.5 Demonstration Site 作為沙箱

為建立機器人,必須為它保留一個 Sametime ID。對於我們的測試和開發,將使用 IBM Lotus Sametime 7.5 Demonstration Site,其中必須建立兩個 Sametime ID,一個用於機器人,而另一個用於可以訪問該機器人的使用者。選擇 File - Preferences,然後在 Preferences 對話方塊的左側導航窗格中選擇 Communities,再單擊 Add New Community 按鈕,來配置 Lotus Sametime Connect,以便連線到 stdemo3.dfw.ibm.com 主伺服器。

在隨後的 Log In 附籤中,輸入 Sametime 使用者的登入資訊(Sametime Demonstration Site 使用者名稱和密碼)。單擊 Server 附籤,如圖 2 所示,在 Host server 欄位中輸入 stdemo3.dfw.ibm.com,在 Community port 欄位中輸入 1533,然後單擊 OK。


圖 2. 新增 Sametime 社群用於測試和開發
新增 Sametime 社群用於測試和開發 

構建並瞭解 StockBot

如前所述,我們正在構建用於提供股票報價資訊的機器人,所以將其命名為 StockBot。問題是如何獲得相關的股票報價資訊?若要實現上述操作,訪問由 Yahoo! Finance Web 站點提供的股票報價資訊。特別地,使用 Yahoo 工具,以逗號分隔值(comma-separated value,CSV)格式返回股票報價。

下面是 IBM 股票程式碼請求的 CSV 返回值:

"IBM",93.86,"N/A"

特別地,我們對第二個記號(本例中的 93.86)感興趣,它是最終成交價(通常被稱為股票報價)。若要獲取此類報價,必須訪問與所查詢的股票程式碼相連線的 URL:

http://finance.yahoo.com/d/quotes.csv?f=sl1e1&e=.csv&s=

例如,如果正在查詢 IBM 的股票報價,URL 為

http://finance.yahoo.com/d/quotes.csv?f=sl1e1&e=.csv&s=IBM

在 URL 中使用 f=sl1e1 來指定希望 Yahoo 返回股票程式碼(由 s 表示)、最終成交價 (l1) 以及讀數誤差 (e1) (如果使用無效程式碼來提供服務時)。稍後,還將使用 java.net 包所提供的 Java 的內建網路工具來聯絡 Yahoo! Finance Web 站點 並獲得所需的股票報價資訊。

建立 StockQuoter 類

這是 com.devworks.example.StockQuoter 類的程式碼。可以從 下載 部分下載該程式碼以及其他與本文相關聯的程式碼。


清單 1. com.devworks.example.StockQuoter 類
public class StockQuoter {
	private static String YAHOO_URL = 
		"http://finance.yahoo.com/d/quotes.csv?f=sl1e1&e=.csv&s=";
	Pattern p = Pattern.compile("N/A");
	private static final float 
		INVALID_SYMBOL_RETURN_VALUE = -999.999F;
	
	public float getQuote(String symbol) throws Exception
	{
		String compositeURL = YAHOO_URL + symbol;
		URL url = new URL(compositeURL);
		InputStream is = url.openStream();
		Reader reader = 
			new BufferedReader(new InputStreamReader(is));
		StreamTokenizer st = new StreamTokenizer(reader);
		// grab the first token - should be the symbol
		st.nextToken();
		String returnedSymbol = st.sval;
		if (!returnedSymbol.equals(symbol)) 
			throw 
			new Exception("A problem occurred with the stock service");
		else  
		{
			st.nextToken(); // skip the comma
			st.nextToken(); // get the quote
			float quote = (float)st.nval;
			st.nextToken(); // skip comma
			st.nextToken(); // get error
			String sError = (String)st.sval;
			Matcher myMatcher = p.matcher(sError);
			boolean found = myMatcher.find();
			if (found) return quote;
			else return INVALID_SYMBOL_RETURN_VALUE;
		}

可以看到,在該類中 java.io.InputStream 物件用於開啟所請求股票程式碼的指定 finance.yahoo.com URL。如前所述,URL 是 finance.yahoo.com URL 和所需報價的程式碼的串聯。使用 StreamTokenizer 類來解析通過訪問 URL 而返回的輸出。接著,查詢股票報價所對應的記號並將它作為 float 值返回。

如果使用者碰巧將無效股票程式碼傳送到 getQuote 方法,那麼 Yahoo 股票服務將返回字串表示發生錯誤。如果一切都正常,則返回的字串是 N/A。請注意正規表示式用於分析出現 N/A 時 Yahoo 的輸出。如果沒有發現一個輸出,則將 dummy 值 -999.99F 返回給方法使用方,將 dummy 值解釋為對無效股票程式碼的呼叫。

除了 getQuote 方法,該類包含主方法,可用於對 getQuote 方法進行單元測試。

上述程式碼必須位於在 Rational Application Developer 中建立的 Dynamic Web Project 的 Java Source 資料夾。對於我們所建立的 Dynamic Web Project,使用了名稱 StockQuoteWebProject。反過來,StockQuoteWebProject 必須位於 Enterprise Application Project 中。我們將 Enterprise Project 命名為 StockQuoteEARProject。該專案結構顯示在 Rational Application Developer 的 Project Explorer 中,如圖 3 所示。


圖 3. Project Explorer 中的 Project 結構
Project Explorer 中的 Project 結構

建立 StockQuote Web 服務

從現在這個角度來說,可以使 Sametime 機器人直接與 StockQuoter 類互動。但是,為了展示 Rational Application Developer 的 Web 服務建立工具,並使用 IDE 嚮導來方便地建立客戶機代理,我們將展示如何建立使用 Web 服務的機器人。

若要在 Rational Application Developer 中將 com.devworks.example.StockQuoter 類公開為 Web 服務,選擇 File - New - Other。在隨後的對話方塊中,確保選中了 Show All Wizards 選項,然後展開 Web Services 目錄,選擇 Web Service 並單擊 Next(參見圖 4)。


圖 4. 選擇 Web Service 嚮導
選擇 Web Service 嚮導

在隨後的 Web Service 窗格中,確保選中了 Web 服務型別 “Java bean Web Service”,並取消選中 Generate a proxy 選項(稍後將生成代理),然後單擊 Next。

在 Object Selection Page 窗格中,確保 Bean 欄位中列出了 com.devworks.example.StockQuoter,然後單擊 Next。在 Service Deployment Configuration 窗格中,確保將 Service project 定義為 StockQuoteWebProject,並將 EAR project 定義為 StockQuoteEARProject(參見圖 5)。


圖 5. 指定用於 Web 服務的專案
指定用於 Web 服務的專案

接下來,確認在 Service Endpoint Interface Selection 窗格中,bean 為 com.devworks.example.StockQuoter, service endpoint interface 為 com.devworks.example.StockQuoter_SEI。不應選中 “Use an existing service endpoint interface” 選項。然後單擊 Next。

在 Web Service Java Bean Identity 窗格中,僅選擇 getQuote 方法,因為不希望通過 Web 服務來公開主方法,然後單擊 Next。最後在 Web Service Publication 窗格中,確保未選中 “Launch the Web Services Explorer to publish this Web service to the Unit Test UDDI Registry” 和 “Launch the Web Services Explorer to publish this Web service to a UDDI Registry” 選項,因為我們並不希望釋出到 UDDI 註冊庫中。

不久,Rational Application Developer 將建立 Web 服務。可以使用 Rational Application Developer 中的各種工具來對 Web 服務進行單元測試。這裡沒有討論該測試過程;如果不熟悉如何實現上述操作,可以參考 參考資料 部分。

請注意 Rational Application Developer 嚮導建立了大量程式碼產品,包括名為 StockQuoter.wsdl 的 Web 服務描述語言(Web Services Description Language,WSDL)檔案。選擇 Dynamic Web Project 並依次展開 StockQuoteWebProject、WebContent、wsdl、com、devworks 以及 example 資料夾後可以看到該檔案。

建立 StockQuote Web Service Client 代理

既然有 Web 服務,則準備消費該服務。通過建立代理 Java 類來處理繁重的工作,Rational Application Developer 允許您避開如何消費 Web 服務這個複雜問題。該代理類與客戶機共存,對於您來說是機器人。簡單起見,假定客戶機和伺服器位於同一機器上。

在 Rational Application Developer 中,選擇 File - New - Other(首先確保在 Select a wizard 視窗中選擇了 Show All Wizards 選項)。展開 Web Services,選擇 Web Service Client,然後單擊 Next。在隨後的 Web Services 窗格中,選擇 Java proxy 作為 Client 代理型別,然後單擊 Next。

接下來,需要告訴 Rational Application Developer 在建立 Web 服務時 WSDL 檔案的建立位置。單擊 Browse 按鈕並從出現的 Resource 瀏覽器視窗依次展開 StockQuoteWebProject、WebContent、wsdl、com、devworks 以及 example 資料夾,再選擇 StockQuoter.wsdl(參見圖 6)。然後單擊 OK。


圖 6. 選擇 StockQuoter.wsdl 檔案
選擇 StockQuoter.wsdl 檔案

在 Client Environment Configuration 窗格中,選擇 Java 作為 Client 型別,然後指定 StockBotProject 作為 Client 專案名稱。稍後將看到,還將使用該專案來放置機器人。在最後一個 Web Service Client 嚮導窗格中,單擊 Finish 來完成 Java 代理的建立(參見圖 7)。


圖 7. 完成 Web Service Client 嚮導
完成 Web Service Client 嚮導

現在,如果切換到 Java 透檢視,應看到名為 StockBotProject 的新專案,其中有大量由 Rational Application Developer 自動生成的類(參見圖 8)。代理類被命名為 StockQuoterProxy.java。


圖 8. 由 Rational Application Developer 自動生成的代理類
由 Rational Application Developer 自動生成的代理類

分析 StockQuoterProxy 類,將發現名為 getQuote 的方法。稍後,將展示 StockBot 如何使用該方法找到股票報價 Web 服務。


建立 StockBot

為了開發 StockBot,使用 Lotus Sametime Java 工具包。使用 Lotus Sametime V7.5 Java 工具包,可以進行這樣操作,即合併公司 Web 站點上的 Sametime 聊天,從而即時連線站點訪問者和公司銷售人員、定製 Lotus Sametime 來滿足業務需求,或者建立自己的啟用了 Sametime 的 Java 應用程式。

首先,必須進行一些內部管理,使 Java 專案為建立 Sametime 機器人做好準備。具體來說,需要將 Lotus Sametime Java 工具包的 STComm.jar、stcommsrvrtk.jar 和 stjavatk.jar 檔案新增到 StockBotProject 的 Java Build Path。若要實現上述操作,請遵循以下步驟:

  1. 在 Rational Application Developer 中,雙擊 Package Explorer 檢視中的 StockBotProject,然後選擇 Properties。
  2. 在 Properties 對話方塊中,選擇左側窗格中的 Java Build Path 來編輯 Java Build Path 屬性。
  3. 選擇 Libraries 附籤(參見圖 9)。
  4. 單擊 Add External JARs 按鈕來新增 Sametime Java Client JAR 檔案。前面所指定的這三個 JAR 檔案包含在 Lotus Sametime Java Toolkit 中。

圖 9. 編輯 Java Build Path 來包含所需的 JAR 檔案
編輯 Java Build Path 來包含所需的 JAR 檔案

StockService 類

Sametime 機器人由兩個類組成,即 StockService 和 StockQuoteBot。大部分機器人邏輯都處於 StockService 類中的,該類實現了以下 Sametime 介面:


清單 2. Sametime 介面
com.lotus.sametime.community.LoginListener
com.lotus.sametime.community.ServiceListener
com.lotus.sametime.im.ImServiceListener
com.lotus.sametime.community.ImListener

在 StockBotProject Java 專案下的 com.devworks.example.bot 包中建立名為 StockService 的類。可以從本文的下載部分匯入該類的程式碼。

現在來分析一下 StockService 類的內容。構造器使用表示會話名的字串來建立新的 STSession 物件,該字串對於執行機器人的 Java Virtual Machine 來說是惟一的。STSession 物件儲存與 Sametime 會話相關聯的元件集。建立了 STSession 物件後,載入機器人所使用的元件並啟動 Sametime 會話。


清單 3. StockService 類
private STSession session;

public StockService(String sessionName) throws DuplicateObjectException {
		session= new STSession(sessionName);            
		session.loadSemanticComponents();
		session.start();
}

建立了 Sametime 會話後,可以加入 Sametime 社群。CommunityService 類允許 StockService 類登入 Lotus Sametime 伺服器。為了使 bot 接收對請求的響應(例如登入請求),必須將 StockService 類與適當的偵聽器相關聯。與 StockService 類相關聯的第一個偵聽器是 com.lotus.sametime.community.ServiceListener。ServiceListener 提供了伺服器端元件可用性的更新,來響應 CommunityService 物件上所作的請求。新增了 ServiceListener 後,將呼叫 private login 方法,如清單 4 所示。


清單 4. CommunityService 類
private CommunityService service;  

  public void start(String server, String username, String password)
  {
      service = (CommunityService)session.getCompApi(CommunityService.COMP_NAME);
      service.addServiceListener(this);
      login(server, username, password);
  }

在下面的 login 方法中,將 com.lotus.sametime.community.LoginListener 關聯到 CommunityService 物件。因為 StockService 類也實現了 LoginListener 介面,可以用此作為引數。關聯了 LoginListener 後,可以使用伺服器名、使用者名稱和密碼登入 Lotus Sametime 伺服器:


清單 5. login 方法
private void login(String server, String username, String password)
  {
    service.addLoginListener(this); 
    service.loginByPassword(server,username,password);
  }

com.lotus.sametime.community.LoginListener 介面有兩個必須實現的回撥方法。成功登入需要 loggedIn 方法,而登出需要 loggedOut 方法。在不成功登入後和成功登出後將呼叫 loggedOut 方法。在實現 loggedOut 方法時,檢視登出的原因,並將它顯示到系統控制檯:


清單 6. loggedOut 方法
public void loggedOut(LoginEvent event)
  {
    int reason = event.getReason();
    if (reason == 0)
    	System.out.println("Successfully logged out.");
    else 
    	System.out.println("Failed to login.  Return Code =" + reason);
    session.stop();
    session.unloadSession();
  }
  

在下面的 loggedIn 方法中,建立了 InstantMessagingService 物件。InstantMessagingService 物件的操作類似於 CommunityService 物件,因為它有很多方法和偵聽器。IMServiceListener 介面允許您偵聽機器人從使用者接收的訊息:


清單 7. loggedIn 方法
InstantMessagingService imService;

  public void loggedIn(LoginEvent event)
  {
	imService = (InstantMessagingService) 
	_session.getCompApi(InstantMessagingService.COMP_NAME);
	imService.registerImType(ImTypes.IM_TYPE_CHAT);
	imService.addImServiceListener(this);
    System.out.println("Logged In");
  }

IMServiceListener 介面有一個回撥方法 imReceived,每當使用者開啟新的即時訊息傳遞視窗時,將呼叫該方法來啟動與機器人的聯絡。若要偵聽使用者從該即時訊息傳遞視窗傳送的訊息和資料,必須建立 ImListener 實現。另外,因為我們的機器人是使用者友好的,所以每當使用者啟動與它的聯絡時將傳送一條歡迎訊息:


清單 8. imReceived 方法
String welcomeMessage = "Welcome to the StockBot. 
Enter a stock symbol.";

public void imReceived(ImEvent arg0) {
	System.out.println("im received");
	arg0.getIm().sendText(false, welcomeMessage);
	arg0.getIm().addImListener(this);
}

StockImListener 回撥方法包括 dataReceived、textReceived、imClosed、openImFailed 和 imOpened。我們的機器人將僅響應 textReceived 方法和 imClosed 方法。當使用者關閉其即時訊息傳遞視窗後,將移除偵聽器,防止機器人將系統資源耗費在不再使用機器人的使用者上:


清單 9. imClosed 方法
public void imClosed(ImEvent arg0) {
	System.out.println("Im Closed");
	arg0.getIm().removeImListener(this);
}

StockBot 對 textReceived 回撥的響應是 StockBot 獲得的別名是什麼。在 textReceived 的實現中,我們獲得了所請求的股票程式碼。然後,呼叫 getQuoteString 來呼叫先前所建立的 Web 服務,getQuoteString 是一種聯絡股票報價 Web 服務的便利方法。如果使用者鍵入 help,機器人將傳送訊息,包含用於與機器人進行互動的指令:


清單 10. textReceived 方法
String helpMessage = "Enter a stock symbol and I will return a price.";

public void textReceived(ImEvent arg0) {
	String stockSymbol = arg0.getText();
	String stringPriceMessage;
	if (stockSymbol.equals("help"))
		stringPriceMessage = helpMessage;
	else
		stringPriceMessage = getQuoteString(stockSymbol);
	arg0.getIm().sendText(true, stringPriceMessage);
}

下面的 getQuoteString 方法包含用於查詢股票程式碼的邏輯,使用了先前所生成的 StockQuoterProxy 類。getQuoteString 方法將返回股票價格或(宣告存在使用者請求問題的)訊息:


清單 11. getQuoteString 方法
private String getQuoteString(String stockSymbol) {
	String stringPriceMessage;
	try {
		float stockPrice = 0.0f;
		StockQuoterProxy proxy = new StockQuoterProxy();
		proxy.getQuote(stockSymbol);
  stockPrice = stockLookup.getQuote(stockSymbol.trim());
		if (stockPrice != -999.99f)
	  stringPriceMessage = 
	  String.valueOf(stockPrice);
		else
		  stringPriceMessage = 
  "I'm sorry I had trouble with your request.";	
	} catch (RemoteException e) {
		stringPriceMessage = 
"I'm sorry I had trouble with your request.";
	} catch (Exception e) {
		stringPriceMessage = 
"I'm sorry I had trouble with your request.";
	}
	return stringPriceMessage;
}

推進帶有 StockQuoteBot 類的 bot

StockQuoteBot 類為 bot 提供命令列功能。該類將檢索它必須連線的 Lotus Sametime 伺服器資訊,以及作為命令列引數的機器人的使用者證照。該類使用先前所討論的 StockService 類的例項來登入。當按下鍵盤上的鍵時,將終止 StockBot:


清單 12. StockQuoteBot 類
public class StockQuoteBot {
	public static void main(String[] args) {
		StockService service = new StockService();
		String server = args[0];
		String userID = args[1];
		String password = args[2];
		service.start(server, userID, password);
		System.out.println("Stock Quote Bot is Running.  Press any key to terminate.");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	try {
			br.readLine();
	} catch (IOException e) {
			System.out.println("error");
	}
		service.stop();
		System.out.println("Stock Quote Bot has terminated");
	}
}

使用 StockBot

既然完成了機器人開發,就可以在 Rational Application Developer 測試環境中方便地執行機器人了。若要實現上述操作,右擊 StockQuoteBot.java 檔案,然後選擇 Run - Run。

現在,將顯示 Run 對話方塊,如圖 10 所示,因此有機會將命令列引數傳遞到 StockBot。在 Configurations 窗格中,選擇 Java Application,然後單擊 New 按鈕。將出現用於 StockQuoteBot 類的新的 Java Application 配置。出現了該配置後,選擇 Arguments 附籤。對於我們的程式來說,輸入的引數是 192.168.19.128 "Stock Quote Bot" ibm,它分別是 Lotus Sametime 伺服器地址、使用者 ID 以及密碼的值。


圖 10. 配置 StockBot,用於 Rational Application Developer 內的工作
配置 StockBot,用於 Rational Application Developer 內的工作

執行了 bot 類之後,將在控制檯中接收確認資訊,表示 Sametime 機器人成功登入(參見圖 11)。


圖 11. 顯示 StockBot 的輸出的 Rational Application Developer 控制檯檢視
顯示 StockBot 的輸出的 Rational Application Developer 控制檯檢視

既然 bot 正在執行,那麼可以登入帶有 Lotus Sametime Connect 的 Lotus Sametime 伺服器,並與 StockBot 進行通訊,如圖 12 所示。若要實現上述操作,必須新增為 StockBot 保留的 Sametime partner ID。


圖 12. 與 StockBot 互動
與 StockBot 互動 

結束語

本文演示瞭如何建立有助於偵聽並響應請求的 Sametime 機器人。特別地,我們構建了股票報價 Web 服務,它的實現將訪問 Yahoo! Finance Web 站點 以獲得報價資訊。然後建立了機器人來訪問 Web 服務;反過來,客戶機可以與機器人交談,並獲得隨需應變的股票報價。

在相關的 developerWorks Lotus 文章 “構建用於語言翻譯的 Lotus Sametime bot” 中,展示瞭如何建立與 IBM WebSphere Translation Server 聯合工作以提供機器翻譯工作的 Sametime 機器人。可以建立的機器人型別僅受您的想象力的限制。我們希望這篇文章使您在構建自己的機器人時可以更自如地使用所需的 API。快樂地構建機器人吧!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-406618/,如需轉載,請註明出處,否則將追究法律責任。

相關文章