非常有趣的問題。我剛剛決定調試,似乎它是真正的本地協議。
呼叫處理從com.google.gwt.dev.shell.BrowserChannel
開始。這個類由BrowserChannelClient和BrowserChannelServer擴展。
而com.google.gwt.dev.shell.BrowserListener
爲來自瀏覽器的新連接創建偵聽器。下面是構造從BrowserListener:
/**
* Listens for new connections from browsers.
*
* @param logger
* @param port
* @param handler
*/
public BrowserListener(final TreeLogger logger, String bindAddress,
int port, final SessionHandlerServer handler) {
try {
listenSocket = new ServerSocket();
listenSocket.setReuseAddress(true);
InetAddress address = InetAddress.getByName(bindAddress);
listenSocket.bind(new InetSocketAddress(address, port));
if (logger.isLoggable(TreeLogger.TRACE)) {
logger.log(TreeLogger.TRACE, "Started code server on port "
+ listenSocket.getLocalPort(), null);
}
listenThread = new Thread() {
@Override
public void run() {
while (true) {
try {
Socket sock = listenSocket.accept();
TreeLogger branch = logger.branch(TreeLogger.TRACE,
"Connection received from "
+ sock.getInetAddress().getCanonicalHostName() + ":"
+ sock.getPort());
try {
sock.setTcpNoDelay(true);
sock.setKeepAlive(true);
} catch (SocketException e) {
// Ignore non-critical errors.
}
BrowserChannelServer server = new BrowserChannelServer(branch,
sock, handler, ignoreRemoteDeath);
/*
* This object is special-cased by the SessionHandler, used for
* methods needed by the client like hasMethod/hasProperty/etc.
* handler is used for this object just to make sure it doesn't
* conflict with some real object exposed to the client.
*/
int id = server.getJavaObjectsExposedInBrowser().add(server);
assert id == BrowserChannel.SPECIAL_SERVERMETHODS_OBJECT;
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Communications error", e);
}
}
}
};
listenThread.setName("Code server listener");
listenThread.setDaemon(true);
} catch (BindException e) {
logger.log(TreeLogger.ERROR, "Unable to bind socket on port " + port
+ " -- is another session active?", e);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Communications error", e);
}
}
太棒了!這正是我要找的。 – minghua