檔案傳輸及離線訊息的獲取 離線訊息和離線檔案的實現
1.檔案的傳送
開一個檔案選擇框,選中檔案後再呼叫下面的方法
public static void sendFile(XMPPConnection connection, String user, File file) throws XMPPException, InterruptedException { System.out.println("傳送檔案開始"+file.getName()); FileTransferManager transfer = new FileTransferManager(Client.getConnection()); System.out.println("傳送檔案給: "+user+Client.getServiceNameWithPre()); OutgoingFileTransfer out = transfer.createOutgoingFileTransfer(user+Client.getServiceNameWithPre()+"/Smack");// out.sendFile(file, file.getName()); System.out.println("//////////"); System.out.println(out.getStatus()); System.out.println(out.getProgress()); System.out.println(out.isDone()); System.out.println("//////////"); System.out.println("傳送檔案結束"); }
2.檔案接收,必須使用監聽
FileTransferManager transfer = new FileTransferManager(connection); transfer.addFileTransferListener(new RecFileTransferListener()); public class RecFileTransferListener implements FileTransferListener { public String getFileType(String fileFullName) { if(fileFullName.contains(".")) { return "."+fileFullName.split("//.")[1]; }else{ return fileFullName; } } @Override public void fileTransferRequest(FileTransferRequest request) { System.out.println("接收檔案開始....."); final IncomingFileTransfer inTransfer = request.accept(); final String fileName = request.getFileName(); long length = request.getFileSize(); final String fromUser = request.getRequestor().split("/")[0]; System.out.println("檔案大小:"+length + " "+request.getRequestor()); System.out.println(""+request.getMimeType()); try { JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); int result = chooser.showOpenDialog(null); if(result==JFileChooser.APPROVE_OPTION) { final File file = chooser.getSelectedFile(); System.out.println(file.getAbsolutePath()); new Thread(){ public void run() { try { System.out.println("接受檔案: " + fileName); inTransfer .recieveFile(new File(file .getAbsolutePath() + getFileType(fileName))); Message message = new Message(); message.setFrom(fromUser); message.setProperty("REC_SIGN", "SUCCESS"); message.setBody("["+fromUser+"]傳送檔案: "+fileName+"/r/n"+"儲存位置: "+file.getAbsolutePath()+ getFileType(fileName)); if (Client.isChatExist(fromUser)) { Client.getChatRoom(fromUser).messageReceiveHandler( message); } else { ChatFrameThread cft = new ChatFrameThread( fromUser, message); cft.start(); } } catch (Exception e2) { e2.printStackTrace(); } } }.start(); }else{ System.out.println("拒絕接受檔案: "+fileName); request.reject(); Message message = new Message(); message.setFrom(fromUser); message.setBody("拒絕"+fromUser+"傳送檔案: "+fileName); message.setProperty("REC_SIGN", "REJECT"); if (Client.isChatExist(fromUser)) { Client.getChatRoom(fromUser) .messageReceiveHandler(message); } else { ChatFrameThread cft = new ChatFrameThread( fromUser, message); cft.start(); } } /* InputStream in = inTransfer.recieveFile(); String fileName = "r"+inTransfer.getFileName(); OutputStream out = new FileOutputStream(new File("d:/receive/"+fileName)); byte[] b = new byte[512]; while(in.read(b) != -1) { out.write(b); out.flush(); } in.close(); out.close();*/ } catch (Exception e) { e.printStackTrace(); } System.out.println("接收檔案結束....."); } }
1.離線訊息
openfire本身是支援離線訊息的,不需要進行額外處理,可以用spark測試下
使用smack,其實他提供了相應的方法
Class OfflineMessageManager
可以看下描述
The OfflineMessageManager helps manage offline messages even before the user has sent an available presence. When a user asks for his offline messages before sending an available presence then the server will not send a flood with all the offline messages when the user becomes online. The server will not send a flood with all the offline messages to the session that made the offline messages request or to any other session used by the user that becomes online.
英文退化了點,汗,大意就是,必須在傳送線上資訊之前去獲取離線訊息
剛開始沒看這個,結果在上線之後,去取,結果。。。。離線訊息數量總是為零,囧
首先,連線,狀態要設為離線
ConnectionConfiguration connConfig = new ConnectionConfiguration(serverDomain);
connConfig.setSendPresence(false); // where connConfig is object of .
connection = new XMPPConnection(connConfig);
connection.connect();
然後,登陸
connection.login(userName, pwd);
接著,拿離線訊息
OfflineMessageManager offlineManager = new OfflineMessageManager(
Client.getConnection());
try {
Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager
.getMessages();
System.out.println(offlineManager.supportsFlexibleRetrieval());
System.out.println("離線訊息數量: " + offlineManager.getMessageCount());
Map<String,ArrayList<Message>> offlineMsgs = new HashMap<String,ArrayList<Message>>();
while (it.hasNext()) {
org.jivesoftware.smack.packet.Message message = it.next();
System.out
.println("收到離線訊息, Received from 【" + message.getFrom()
+ "】 message: " + message.getBody());
String fromUser = message.getFrom().split("/")[0];
if(offlineMsgs.containsKey(fromUser))
{
offlineMsgs.get(fromUser).add(message);
}else{
ArrayList<Message> temp = new ArrayList<Message>();
temp.add(message);
offlineMsgs.put(fromUser, temp);
}
}
//在這裡進行處理離線訊息集合......
Set<String> keys = offlineMsgs.keySet();
Iterator<String> offIt = keys.iterator();
while(offIt.hasNext())
{
String key = offIt.next();
ArrayList<Message> ms = offlineMsgs.get(key);
TelFrame tel = new TelFrame(key);
ChatFrameThread cft = new ChatFrameThread(key, null);
cft.setTel(tel);
cft.start();
for (int i = 0; i < ms.size(); i++) {
tel.messageReceiveHandler(ms.get(i));
}
}
offlineManager.deleteMessages();
} catch (Exception e) {
e.printStackTrace();
}
記得最後要把離線訊息刪除,即通知伺服器刪除離線訊息
offlineManager.deleteMessages();
否則,下次上了訊息還存在
接著,上線
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
2.離線檔案
這個我沒實現,汗
主要思想:開發openfire外掛,攔截離線檔案,將檔案存到伺服器上,同時在資料庫裡開一張表,儲存檔案資訊
當用戶上線時,查表,若是有,根據路徑,拿了傳送
當然,大家可以谷歌下是否有相應的外掛,時間緊迫,我倒是沒找著
到這裡,大概就這些了,對了,還擴充套件了個視訊音訊聊天,不過使用的是JMF,點對點的,本來打算使用jingle的,結果連API文件都沒找到,暈死
就這些
轉自:http://www.myexception.cn/mobile/1310046.html