Created
July 28, 2009 02:41
-
-
Save itszero/156891 to your computer and use it in GitHub Desktop.
VMPServer 的參考原始碼
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tw.mpclab.VMP.Server; | |
import org.json.JSONObject; | |
public abstract class VMPASyncCallbackListener { | |
public abstract void onCallback(JSONObject obj); | |
public void onFinish() { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tw.mpclab.VMP.Server; | |
import java.util.Date; | |
import org.json.*; | |
import tw.mpclab.VMP.R; | |
import tw.mpclab.VMP.Utilities.VMPAlertDialog; | |
import android.content.Context; | |
import android.util.Log; | |
import com.google.android.maps.GeoPoint; | |
public final class VMPMessage{ | |
public String type; | |
public String nickname; | |
public String cid; | |
public GeoPoint geo; | |
public String secret; | |
public Context ctx; | |
public String result; | |
public String gid; | |
public String join_key; | |
public String name; | |
public String mime_type; | |
public String message; | |
public int id; | |
public JSONArray messages; | |
public JSONObject payload; | |
public Date created_at; | |
public VMPMessage(){ | |
this.result = "fail"; | |
} | |
public VMPMessage(JSONObject jobj, Context c) throws JSONException{ | |
if(jobj.has("result") && jobj.getString("result").equalsIgnoreCase("fail")){ | |
try | |
{ | |
VMPAlertDialog AB = new VMPAlertDialog(c); | |
AB.setMessage(jobj.getString("message")); | |
AB.setTitle("Oops!"); | |
AB.setCancelButton(ctx.getString(R.string.btn_OK)); | |
AB.showThis(); | |
} | |
catch(Exception ex) | |
{ | |
Log.e("VMPMessage", "Oops! " + jobj.optString("message")); | |
} | |
} | |
this.ctx = c; | |
setvars(jobj); | |
} | |
private void setvars(JSONObject jobj) throws JSONException{ | |
this.result = jobj.optString("result"); | |
this.type = jobj.optString("type"); | |
this.nickname = jobj.optString("nickname"); | |
this.cid = jobj.optString("cid"); | |
if(jobj.has("type") && this.type.equalsIgnoreCase("location")){ | |
JSONObject objPayload = new JSONObject(jobj.optString("payload")); | |
int lat = (int)(objPayload.getDouble("lat") * 1000000); | |
int lon = (int)(objPayload.getDouble("lon") * 1000000); | |
this.geo = new GeoPoint(lat, lon); | |
} | |
this.secret = jobj.optString("secret"); | |
this.gid = jobj.optString("gid"); | |
this.join_key = jobj.optString("join_key"); | |
this.name = jobj.optString("name"); | |
this.messages = jobj.optJSONArray("messages"); | |
if (jobj.has("payload")) | |
this.payload = new JSONObject(jobj.optString("payload")); | |
if (jobj.has("created_at")){ | |
this.created_at = new Date(jobj.optLong("created_at")); | |
} | |
this.mime_type = jobj.optString("mime_type"); | |
this.message = jobj.optString("message"); | |
this.id = jobj.optInt("id"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tw.mpclab.VMP.Server; | |
import java.util.Date; | |
import com.google.android.maps.GeoPoint; | |
public final class VMPPerson{ | |
public String nickname; | |
public GeoPoint geo,pinGeo; | |
public String clientMsg; | |
public String cid; | |
public Date created_at; | |
public String msgType; | |
public String msgReply; | |
public String voicePayload; | |
public VMPPerson(String cid) | |
{ | |
this.cid = cid; | |
this.created_at = new Date(0, 1, 2); | |
} | |
public void setMsg(String msg, String type, String alReply){ | |
this.clientMsg = msg; | |
this.msgType = type; | |
if(alReply != null) | |
this.msgReply = alReply; | |
} | |
public void setNickname(String nick){ | |
this.nickname = nick; | |
} | |
public void setGeo(GeoPoint g){ | |
this.geo = g; | |
} | |
public void setCreatedAt(Date create){ | |
this.created_at = create; | |
} | |
public void setVoicePayload(String str){ | |
this.voicePayload = str; | |
} | |
public void setPinGeo(GeoPoint geo){ | |
this.pinGeo = geo; | |
} | |
@Override | |
public boolean equals(Object v){ | |
return this.cid.equals((String)v); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tw.mpclab.VMP.Server; | |
import java.util.HashMap; | |
public class VMPRequest { | |
public String method; | |
public String http_method; | |
public HashMap<String,String> params; | |
public VMPASyncCallbackListener callback; | |
public int retries; | |
public Boolean blocking; | |
public VMPRequest(String m, String h, HashMap<String, String> p, VMPASyncCallbackListener r) | |
{ | |
method = m; | |
http_method = h; | |
params = p; | |
callback = r; | |
retries = 10; | |
blocking = false; | |
} | |
public void setBlocking(Boolean b) | |
{ | |
blocking = b; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tw.mpclab.VMP.Server; | |
import java.io.*; | |
import java.net.*; | |
import org.json.*; | |
import tw.mpclab.VMP.R; | |
import android.app.AlertDialog; | |
import android.content.Context; | |
import android.os.Handler; | |
import android.view.WindowManager; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.TreeSet; | |
public final class VMPServer{ | |
private static VMPServer instance = null; | |
private String HostName; | |
private URL connurl; | |
private URLConnection conn; | |
private HttpURLConnection httpConn; | |
private BufferedReader FromServer; | |
private OutputStreamWriter toServer; | |
private JSONObject Jobj; | |
private String secret; | |
public String ssss; | |
private LinkedList<VMPRequest> queue; | |
public Context ctx; | |
public long lastWarning = -1; | |
public static synchronized VMPServer getInstance() | |
{ | |
if (instance == null) | |
instance = new VMPServer(); | |
return instance; | |
} | |
private VMPServer() {} | |
public VMPServer(String Host, Context c){ | |
this.HostName = Host; | |
instance = this; | |
ctx = c; | |
queue = new LinkedList<VMPRequest>(); | |
new PoolWorker().start(); | |
} | |
public void setSecret(String s){ | |
this.secret = s; | |
} | |
public void postMessageASync(String U, String method, HashMap<String,String> H, Boolean blocking, VMPASyncCallbackListener r) { | |
synchronized(queue) | |
{ | |
VMPRequest req = new VMPRequest(U, method, H, r); | |
req.setBlocking(blocking); | |
queue.add(req); | |
queue.notify(); | |
} | |
} | |
public JSONObject postMessage(String U, String method, HashMap<String,String> H) throws IOException,JSONException { | |
try | |
{ | |
Jobj = new JSONObject(postMessageRawString(U, method, H, false)); | |
} | |
catch(Exception ex) | |
{ | |
Jobj = null; | |
} | |
return Jobj; | |
} | |
public String postMessageRawString(String U, String method, HashMap<String,String> H, final Boolean blocking) throws JSONException{ | |
StringBuilder sbData = new StringBuilder(); | |
try | |
{ | |
if(H.containsKey("cid")){ | |
String sig = signature(H); | |
H.put("sig", sig); | |
} | |
U = U.replace(HostName, ""); | |
this.connect(U,method); | |
String strSend = new String(); | |
toServer = new OutputStreamWriter(this.httpConn.getOutputStream()); | |
int i=0; | |
for(String key: H.keySet()){ | |
if(i != 0) | |
strSend += "&"; | |
strSend += (URLEncoder.encode(key).replace(" ", "%20") + "=" + URLEncoder.encode(H.get(key)).replace("+", "%20")); | |
i=1; | |
} | |
toServer.write(strSend); | |
toServer.close(); | |
FromServer = new BufferedReader(new InputStreamReader(this.httpConn.getInputStream())); | |
String str; | |
while((str = FromServer.readLine()) != null){ | |
sbData.append(str); | |
} | |
FromServer.close(); | |
} | |
catch(IOException ex) | |
{ | |
Handler mHandler = new Handler(ctx.getMainLooper()); | |
mHandler.post(new Runnable(){ | |
@Override | |
public void run () | |
{ | |
try | |
{ | |
if (blocking || (System.currentTimeMillis() - lastWarning > 10 * 1000 && !blocking)) | |
new AlertDialog.Builder(ctx).setMessage(R.string.network_fail).setNeutralButton(R.string.btn_OK, null).show(); | |
lastWarning = System.currentTimeMillis(); | |
} | |
catch(WindowManager.BadTokenException ex) | |
{ | |
// Just ignore if there is no active activity | |
} | |
} | |
}); | |
} | |
return sbData.toString(); | |
} | |
public JSONObject getMessage(String U,String method) throws IOException,JSONException{ | |
return postMessage(U,method,new HashMap<String,String>()); | |
} | |
private Object[] sortASC(HashMap<String,String> H){ | |
List<String> mapKeys = new ArrayList<String>(H.keySet()); | |
TreeSet<String> sortedSet = new TreeSet<String>(mapKeys); | |
Object[] sortedArray = sortedSet.toArray(); | |
return sortedArray; | |
} | |
private void connect(String U,String method) throws IOException{ | |
this.connurl = new URL(this.HostName + U); | |
this.conn = this.connurl.openConnection(); | |
if (!(this.conn instanceof HttpURLConnection)) | |
throw new IOException("Not an HTTP connection."); | |
this.httpConn = (HttpURLConnection) conn; | |
this.httpConn.setInstanceFollowRedirects(true); | |
this.httpConn.setRequestMethod(method.toUpperCase()); | |
this.httpConn.setDoOutput(true); | |
} | |
private String byte2hex(byte[] b) //二進位制轉字串 | |
{ | |
String hs=""; | |
String stmp=""; | |
for (int n=0;n<b.length;n++) | |
{ | |
stmp=(java.lang.Integer.toHexString(b[n] & 0XFF)); | |
if (stmp.length()==1) hs=hs+"0"+stmp; | |
else hs=hs+stmp; | |
if (n<b.length-1) hs=hs+""; | |
} | |
return hs.toLowerCase(); | |
} | |
private String signature(HashMap<String,String> H){ | |
String sig = new String(); | |
String strCom = new String(); | |
Object[] sorted; | |
sorted = sortASC(H); | |
int i=0; | |
for(i=0;i<sorted.length;i++){ | |
if(i != 0) | |
strCom += "&"; | |
strCom += (URLEncoder.encode(sorted[i].toString()).replace(" ", "%20") + "=" + URLEncoder.encode(H.get(sorted[i].toString())).replace("+", "%20")); | |
} | |
strCom += this.secret; | |
MessageDigest digest; | |
try { | |
digest = MessageDigest.getInstance("SHA-1"); | |
digest.reset(); | |
sig = byte2hex(digest.digest(strCom.getBytes("UTF-8"))); | |
} catch (NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
ssss = sig; | |
return sig; | |
} | |
private class PoolWorker extends Thread { | |
public void run() | |
{ | |
VMPRequest r; | |
while(true) | |
{ | |
synchronized(queue) | |
{ | |
while (queue.isEmpty()) | |
{ | |
try | |
{ | |
queue.wait(); | |
} | |
catch (InterruptedException ignored) {} | |
} | |
r = queue.removeFirst(); | |
r.retries--; | |
} | |
try { | |
JSONObject obj = VMPServer.getInstance().postMessage(r.method, r.http_method, r.params); | |
if (obj != null && r.callback != null) | |
r.callback.onCallback(obj); | |
if (r.callback != null) | |
r.callback.onFinish(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
if (r.retries > 0) | |
queue.add(r); | |
} | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException ignored) {} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tw.mpclab.VMP.Server.VMPASyncCallbackListener; | |
import tw.mpclab.VMP.Server.VMPMessage; | |
import tw.mpclab.VMP.Server.VMPServer; | |
// ... // | |
private VMPServer server = VMPServer.getInstance(); | |
// 用 HashMap 傳入參數 | |
HashMap<String,String> H = new HashMap<String,String>(); | |
H.put("cid", bun.getString("cid")); | |
H.put("join_key",msg); | |
// 發送 Request | |
server.postMessageASync("groups/join", "post", H, true, new VMPASyncCallbackListener() { | |
@Override | |
public void onFinish() | |
{ | |
// Request結束的時候會被呼叫 | |
} | |
@Override | |
public void onCallback(JSONObject obj) { | |
// 獲得結果的時候會被呼叫 | |
// 利用 VMPMessage 解析 JSON 回傳資料 | |
VMPMessage vm; | |
vm = new VMPMessage(obj, Join.this.getApplicationContext()); | |
// 使用 VMPMessage 做你想做的事情 | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment