XMPP協定已一統即時訊息協定標準

| 1 TrackBack

自由軟體鑄造場得知Microsoft 打開 Messenger 大門 開始支援 XMPP,因此目前主流即時訊息都支援XMPP,包括Facebook chat

既然如此,當然找看看熟悉的Smack套件是否也有MSN的sample code。果然Github上有MS放出的LiveSDK,便有JAVAAndroid的程式碼。有空再把拿token那程式改成用httpclient
JAVA程式碼如下:

package messenger;


import java.net.URL;

import java.net.URLDecoder;


import javax.swing.JOptionPane;


import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.PacketListener;

import org.jivesoftware.smack.Roster;

import org.jivesoftware.smack.RosterEntry;

import org.jivesoftware.smack.SASLAuthentication;

import org.jivesoftware.smack.XMPPConnection;

import org.jivesoftware.smack.XMPPException;

import org.jivesoftware.smack.filter.MessageTypeFilter;

import org.jivesoftware.smack.filter.PacketFilter;

import org.jivesoftware.smack.filter.PacketTypeFilter;

import org.jivesoftware.smack.packet.Message;

import org.jivesoftware.smack.packet.Packet;

import org.jivesoftware.smack.packet.Presence;

import org.jivesoftware.smack.util.StringUtils;


/**

 * XmppClient class has all the XMPP specific logic. This class uses smack

 * library to connect to windows live messenger service. For Windows Live Xmpp

 * documentation see <link>

 */

public class msn {


public static final String Host = "xmpp.messenger.live.com";

public static final int Port = 5222;

public static final String Service = "messenger.live.com";


private String accessToken;

private XMPPConnection connection;


/**

* This block initializes smack with SASL mechanism used by Windows Live.

*/

static {

SASLAuthentication.registerSASLMechanism("X-MESSENGER-OAUTH2",

XMessengerOAuth2.class);

SASLAuthentication.supportSASLMechanism("X-MESSENGER-OAUTH2");

}


public static void main(String[] args) throws InterruptedException {

/**

* 1. Set up a string with the path to the website.

* 2. Create a desktop variable.  The desktop class uses the computer's default browser to open the URL.

* 3. Load the URL.

* 4. Browse to the URL.

*/


//TODO put your own clientId here.

//String clientId = "000000004807AE0A";

//String scopes = "wl.messenger";

//String signInUrl = "https://oauth.live.com/authorize?client_id=" + clientId + "&redirect_uri=https://oauth.live.com/desktop&response_type=token&scope=" + scopes;


try {

// launch a web browser to take the user through the OAuth 2.0 consent flow

//BareBonesBrowserLaunch.browse(signInUrl);


// pop a dialog that tells the developer to copy and paste the URL and put it into a text box in the dialog

//String returnUrlString = (String)JOptionPane.showInputDialog("After completing the OAuth consent flow in the browser, copy and paste the return URL into this dialog box");

String returnUrlString = "https://oauth.live.com/desktop#access_token=EwAoAq1DBAAUlbRWyAJjK5w968Ru3Cyt%2f6GvwXwAAcQc5qjgPRbE4InoTBM3bsPTd0eAZIcSZiRxdNSMn3K8jSLvqJjDBfhjf3fd71C%2fBlGBFqDAs%2fFZYb1WYDPUfbL239Y3sXKA8ZFZgMOKIWWb%2beib%2fyTpNIW6m4O4SUMhAu5GYe3DAiC7JsXAnLgu%2bUFeUpF%2fEMjmrdRGzVDUjNNuwfKgdqpgvBD5kWAU1A3NNGhwxJZZhwOpKcogIcWZ%2fR7eKdFsYjGN9riWjBh2gcmk%2bGiEMifAxI0PoqeECqq9otHAZ1fz9NxCUbFssIQuy5mxlzjPu%2fWl9wmwRvZnHkDY4EiuDrfUw6SHflWirQ74nQ2fjv7Ew7Dk4nl%2fvvTymxcDZgAACPsOZ%2fNUm4kh%2bABDsVcnU0eMbHeEikN9WrYIwYTrTQKy2WtThAVuuNwsJOiqgyP%2fInBCWZMudPy0qGOlFoJriKm16OiYrgf44t9aua6MO7Lq0hJchmmbBm9%2fEsSquOhKaLOrNgx%2fVPs%2bqycd6sBkqzPJMD69eIztb%2fPnllMbX%2f4qDz1cUU1ySkE%2f3%2bMlENfPDKiNARAvKxSpljsM6yjMgwPCTawChrUgExYjbeGxAR16vY1N7ibTmwcgIB9ewoyghGeNBI7GHBdpOMzBbp%2b6YZQYBDHwPc7SXYoxPq1s8TAlfdXrrpj2J2kEpxuwPGM6VnBJN1yOdFsolRENflmAkTCh4gAA&token_type=bearer&expires_in=3600&scope=wl.messenger";

// take the string URL from the dialog and programmatically cram it into the access token parameter

String accessToken = urlTokenizerHelper(returnUrlString);


// log in using the access token

msn client = new msn(accessToken);

client.logIn();

Roster r = client.getRoster();

System.out.println(r.toString());

// make sure the program hasn't already closed before the login has completed

// in a real XMPP client, this would be replaced with waiting on UI events and Xmpp events 

Thread.sleep(1000000);

} catch (Exception e) {

System.out.println(e);

}

}


/**

* This function helps to extract the access_token query string parameter from the return URL.

*/

public static String urlTokenizerHelper(String urlString) {

URL returnUrl = null;

try{

returnUrl = new URL(urlString);

}catch(Exception e){}

String queryParameters = returnUrl.getRef();

queryParameters = queryParameters.substring(queryParameters.indexOf("access_token"));

queryParameters = queryParameters.substring(queryParameters.indexOf("=")+1);


String encodedAccessToken = queryParameters.substring(0, queryParameters.indexOf("&"));


return URLDecoder.decode(encodedAccessToken);


}

/**

* Constructor

* @param accessToken

*            The OAuth2.0 access token to be used for login.

*/

public msn(String accessToken) {

this.accessToken = accessToken;

}


/**

* Get the Roster for this client instance.

* @return The full Roster for the client.

*/

public Roster getRoster() {

return this.connection.getRoster();

}


/**

* Get the Jid for this client instance.

*/

public String getLocalJid() {

return StringUtils.parseBareAddress(this.connection.getUser());

}


/**

* Log in the client to the messenger service.

*/

public void logIn() {


// Create a connection. We use service name in config and asmack will do

// SRV look up locate the xmpp server.

ConnectionConfiguration connConfig = new ConnectionConfiguration(

msn.Service);

connConfig.setRosterLoadedAtLogin(true);

this.connection = new XMPPConnection(connConfig);


try {

this.connection.connect();


// We do not need user name in this case.

this.connection.login("", this.accessToken);

} catch (XMPPException ex) {

this.connection = null;

return;

}


System.out.println(String.format("Logged in as %s",

this.connection.getUser()));

// set the message and presence handlers

this.setPacketFilters();


// Set the status to available

Presence presence = new Presence(Presence.Type.available);

this.connection.sendPacket(presence);

}


/**

* Send a text message to the buddy.

* @param to

*            The Buddy Jid.

* @param text

*            The text message to be sent.

*/

public void sendMessage(String to, String text) {

Message msg = new Message(to, Message.Type.chat);

msg.setBody(text);

this.connection.sendPacket(msg);

}


/**

* Set the packet filters for handling incoming stanzas.

*/

private void setPacketFilters() {

if (this.connection != null) {

PacketFilter presenceFilter = new PacketTypeFilter(Presence.class);

this.connection.addPacketListener(new PacketListener() {

public void processPacket(Packet packet) {

Presence presence = (Presence) packet;

handlePresenceReceived(presence);

}

}, presenceFilter);


PacketFilter messageFilter = new MessageTypeFilter(

Message.Type.chat);

this.connection.addPacketListener(new PacketListener() {

public void processPacket(Packet packet) {

Message message = (Message) packet;

if (message.getBody() != null) {

handleMessageReceived(message);

}

}

}, messageFilter);

}

}


/**

* Handle the presence stanza received.

* @param presence

*            The received presence stanza.

*/

private void handlePresenceReceived(Presence presence) {

String from = StringUtils.parseBareAddress(presence.getFrom());

System.out.println(String.format(

"Presence received from Jid: %s, Name: %s", from,

this.getContactName(from)));

}


/**

* Handle the message stanza received.

* @param message

*            The received message stanza.

*/

private void handleMessageReceived(Message message) {

String from = StringUtils.parseBareAddress(message.getFrom());

System.out.println(String.format(

"Message received from Jid: %s, Name: %s", from,

this.getContactName(from)));

}


/**

* Get friendly name of a contact given the jid.

* @param jid

*            Jid for the target contact.

* @return The friendly name by looking up roster.

*/

private String getContactName(String jid) {

Roster roster = this.connection.getRoster();

RosterEntry entry = roster.getEntry(jid);

return entry.getName();

}

}


1 TrackBack

TrackBack URL: http://server.everfine.com.tw/blog/mt-tb.cgi/317

之前說到XMPP已經成為即時訊息的標準,那就利用Facebook手機即時通的便捷快速來送Facebook Chat訊息。 其實只要拿之前GTalk的程式碼,稍微修改一下,就可發送了。其中差異在於DIGEST-MD5的認證機制。在Smack討論區已經有人實作出XMPP DIGEST-MD5的物件。只要將login部份加上DIGEST-MD5認證。 完整程式碼如下: package messenger;import java.io.BufferedReader;import java.io.IOExc... Read More

February 2012

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

Archives

Powered by Movable Type 4.34-en

About this Entry

This page contains a single entry by philipz published on January 3, 2012 10:22 AM.

建置程式交易系統(2) - 決定獲利策略 was the previous entry in this blog.

Using Smack XMPP API to send Facebook Chat Messages is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.