[Android] PhoneGap 소스 코드 분석 - CallbackServer 비동기 리 셋
먼저 js 엔 드 관련 코드 를 살 펴 보 겠 습 니 다.
// file: lib/android/plugin/android/callback.js
define("cordova/plugin/android/callback", function(require, exports, module) {
var port = null,
token = null,
xmlhttp;
function startXhr() {
// cordova/exec depends on this module, so we can't require cordova/exec on the module level.
var exec = require('cordova/exec'),
xmlhttp = new XMLHttpRequest();
// Callback function when XMLHttpRequest is ready
xmlhttp.onreadystatechange=function(){
if (!xmlhttp) {
return;
}
if (xmlhttp.readyState === 4){
// If callback has JavaScript statement to execute
if (xmlhttp.status === 200) {
// Need to url decode the response
var msg = decodeURIComponent(xmlhttp.responseText);
setTimeout(startXhr, 1);
exec.processMessages(msg);
}
// If callback ping (used to keep XHR request from timing out)
else if (xmlhttp.status === 404) {
setTimeout(startXhr, 10);
}
// 0 == Page is unloading.
// 400 == Bad request.
// 403 == invalid token.
// 503 == server stopped.
else {
console.log("JSCallback Error: Request failed with status " + xmlhttp.status);
exec.setNativeToJsBridgeMode(exec.nativeToJsModes.POLLING);
}
}
};
if (port === null) {
port = prompt("getPort", "gap_callbackServer:");
}
if (token === null) {
token = prompt("getToken", "gap_callbackServer:");
}
xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true);
xmlhttp.send();
}
module.exports = {
start: function() {
startXhr();
},
stop: function() {
if (xmlhttp) {
var tmp = xmlhttp;
xmlhttp = null;
tmp.abort();
}
},
isAvailable: function() {
return ("true" != prompt("usePolling", "gap_callbackServer:"));
}
};
});
주요 처 리 는 startXhr 함수 입 니 다.자바 의 server 쪽 에 ajax 요청 을 했 습 니 다. onready statechange 라 는 반전 함수 에서 server 쪽 이 결 과 를 되 돌려 주 기 를 기다 리 고 있 습 니 다.server 엔 드 가 돌아 온 결과 가 정확 하 다 면 setTimeout (startXhr, 1) 함 수 를 통 해 1 호 초 후에 server 엔 드 에 ajax 요청 을 다시 합 니 다.server 에서 돌아 온 결과 상태 가 404 이면 10 호 초 간격 으로 server 쪽 에 ajax 요청 을 다시 합 니 다.
다음은 server 엔 드 가 어떻게 처리 되 는 지 살 펴 보 겠 습 니 다.server 엔 드 의 처리 코드 는 CallbackServer. 자바 의 run () 방법 입 니 다.
서버 쪽 의 원본 코드 를 먼저 봅 니 다:
이것 은 server Socket 을 통 해 http 의 server 단 을 모 의 합 니 다.그 중에서 jsMessage Queue 는 자바 에서 보 낸 js 메시지 입 니 다. server Socket 은 클 라 이언 트 (js 엔 드) 의 요청 을 받 은 후에 jsMessage Queue 의 js 코드 를 클 라 이언 트 (js 엔 드) 에 보 냅 니 다.
/**
* Start running the server.
* This is called automatically when the server thread is started.
*/
public void run() {
// Start server
try {
this.active = true;
String request;
waitSocket = new ServerSocket(0);
this.port = waitSocket.getLocalPort();
//Log.d(LOG_TAG, "CallbackServer -- using port " +this.port);
this.token = java.util.UUID.randomUUID().toString();
//Log.d(LOG_TAG, "CallbackServer -- using token "+this.token);
while (this.active) {
//Log.d(LOG_TAG, "CallbackServer: Waiting for data on socket");
Socket connection = waitSocket.accept();
BufferedReader xhrReader = new BufferedReader(new InputStreamReader(connection.getInputStream()), 40);
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
request = xhrReader.readLine();
String response = "";
//Log.d(LOG_TAG, "CallbackServerRequest="+request);
if (this.active && (request != null)) {
if (request.contains("GET")) {
// Get requested file
String[] requestParts = request.split(" ");
// Must have security token
if ((requestParts.length == 3) && (requestParts[1].substring(1).equals(this.token))) {
//Log.d(LOG_TAG, "CallbackServer -- Processing GET request");
String payload = null;
// Wait until there is some data to send, or send empty data every 10 sec
// to prevent XHR timeout on the client
while (this.active) {
if (jsMessageQueue != null) {
payload = jsMessageQueue.popAndEncode();
if (payload != null) {
break;
}
}
synchronized (this) {
try {
this.wait(10000); // prevent timeout from happening
//Log.d(LOG_TAG, "CallbackServer>>> break <<<");
break;
} catch (Exception e) {
}
}
}
// If server is still running
if (this.active) {
// If no data, then send 404 back to client before it times out
if (payload == null) {
//Log.d(LOG_TAG, "CallbackServer -- sending data 0");
response = "HTTP/1.1 404 NO DATA\r
\r
"; // need to send content otherwise some Android devices fail, so send space
}
else {
//Log.d(LOG_TAG, "CallbackServer -- sending item");
response = "HTTP/1.1 200 OK\r
\r
";
response += encode(payload, "UTF-8");
}
}
else {
response = "HTTP/1.1 503 Service Unavailable\r
\r
";
}
}
else {
response = "HTTP/1.1 403 Forbidden\r
\r
";
}
}
else {
response = "HTTP/1.1 400 Bad Request\r
\r
";
}
//Log.d(LOG_TAG, "CallbackServer: response="+response);
//Log.d(LOG_TAG, "CallbackServer: closing output");
output.writeBytes(response);
output.flush();
}
output.close();
xhrReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
this.active = false;
//Log.d(LOG_TAG, "CallbackServer.startServer() - EXIT");
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.