【问题标题】:Use Plugin in PhoneGap/Cordova 2.9.0 for mDNS/ZeroConf/Bonjour使用 PhoneGap/Cordova 2.9.0 中的插件进行 mDNS/ZeroConf/Bonjour
【发布时间】:2014-04-22 16:01:23
【问题描述】:

我正在为 Android 制作我的第一个 PhoneGap 应用,它需要 mDNS 解析。由于“.local”地址无法在 Android 上解析(v4.1 之前),我使用了带有 JmDNS.jar 文件的 ZeroConf 库.我参考了this GitHub repository的插件,你可能想看看。

ZeroConf.java

public PluginResult execute(String action, JSONArray args, String callbackId) {
    this.callback = callbackId;

    if (action.equals("watch")) {
        String type = args.optString(0);
        if (type != null) {
            watch(type);
        } else {
            return new PluginResult(PluginResult.Status.ERROR, "Service type not specified");
        }
    } else if (action.equals("unwatch")) {
        String type = args.optString(0);
        if (type != null) {
            unwatch(type);
        } else {
            return new PluginResult(PluginResult.Status.ERROR, "Service type not specified");
        }
    } else if (action.equals("register")) {
        JSONObject obj = args.optJSONObject(0);
        if (obj != null) {
            String type = obj.optString("type");
            String name = obj.optString("name");
            int port = obj.optInt("port");
            String text = obj.optString("text");
            if(type == null) {
                return new PluginResult(PluginResult.Status.ERROR, "Missing required service info");
            }
            register(type, name, port, text);
        } else {
            return new PluginResult(PluginResult.Status.ERROR, "Missing required service info");
        }

    } else if (action.equals("close")) { 
        if(jmdns != null) {
            try {
                jmdns.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }  else if (action.equals("unregister")) {
        if(jmdns != null) {
            jmdns.unregisterAllServices();
        }

    } else {
        Log.e("ZeroConf", "Invalid action: " + action);
        return new PluginResult(PluginResult.Status.INVALID_ACTION);
    }
    PluginResult result = new PluginResult(Status.NO_RESULT);
    result.setKeepCallback(true);
    return result;
}

private void watch(String type) {
    if(jmdns == null) {
        setupWatcher();
    }
    Log.d("ZeroConf", "Watch " + type);
    Log.d("ZeroConf", "Name: " + jmdns.getName() + " host: " + jmdns.getHostName());
    jmdns.addServiceListener(type, listener);
}
private void unwatch(String type) {
    if(jmdns == null) {
        return;
    }
    jmdns.removeServiceListener(type, listener);
}

private void register (String type, String name, int port, String text) {
    if(name == null) {
        name = "";
    }

    if(text == null) {
        text = "";
    }

     try {
         ServiceInfo service = ServiceInfo.create(type, name, port, text);
        jmdns.registerService(service);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void setupWatcher() {
    Log.d("ZeroConf", "Setup watcher");
     WifiManager wifi = (WifiManager) this.cordova.getActivity().getSystemService(android.content.Context.WIFI_SERVICE);
    lock = wifi.createMulticastLock("ZeroConfPluginLock");
    lock.setReferenceCounted(true);
    lock.acquire();
    try {
        jmdns = JmDNS.create();
        listener = new ServiceListener() {

            public void serviceResolved(ServiceEvent ev) {
                Log.d("ZeroConf", "Resolved");

                sendCallback("added", ev.getInfo());
            }

            public void serviceRemoved(ServiceEvent ev) {
                Log.d("ZeroConf", "Removed");

                sendCallback("removed", ev.getInfo());
            }

            public void serviceAdded(ServiceEvent event) {
                Log.d("ZeroConf", "Added");

                // Force serviceResolved to be called again
                jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
            }
        };

    } catch (IOException e) {
        e.printStackTrace();
        return;
    }
}

public void sendCallback(String action, ServiceInfo info) {
    JSONObject status = new JSONObject();
    try {
        status.put("action", action);
        status.put("service", jsonifyService(info));
        Log.d("ZeroConf", "Sending result: " + status.toString());

        PluginResult result = new PluginResult(PluginResult.Status.OK, status);
        result.setKeepCallback(true);
        this.success(result, this.callback);

    } catch (JSONException e) {

        e.printStackTrace();
    }


}


public static JSONObject jsonifyService(ServiceInfo info) {
    JSONObject obj = new JSONObject();
    try {
        obj.put("application", info.getApplication());
        obj.put("domain", info.getDomain());
        obj.put("port", info.getPort());
        obj.put("name", info.getName());
        obj.put("server", info.getServer());
        obj.put("description", info.getNiceTextString());
        obj.put("protocol", info.getProtocol());
        obj.put("qualifiedname", info.getQualifiedName());
        obj.put("type", info.getType());

        JSONArray addresses = new JSONArray();
        String[] add = info.getHostAddresses();
        for(int i = 0; i < add.length; i++) {
            addresses.put(add[i]);
        }
        obj.put("addresses", addresses);
        JSONArray urls = new JSONArray();

        String[] url = info.getURLs();
        for(int i = 0; i < url.length; i++) {
            urls.put(url[i]);
        }
        obj.put("urls", urls);

    } catch (JSONException e) {
        e.printStackTrace();
        return null;
    }

    return obj;

}

ZeroConf.js

var ZeroConf = {
watch: function(type, callback) {
    return cordova.exec(function(result) {
        if(callback) {
            callback(result);
        }

    }, ZeroConf.fail, "ZeroConf", "watch", [type]);
},
unwatch: function(type) {
    return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unwatch", [type]);
},
close: function() {
    return cordova.exec(null, ZeroConf.fail, "ZeroConf", "close", [])
},
register: function(type, name, port, text) {
    if(!type) {
        console.error("'type' is a required field");
        return;
    }
    return cordova.exec(null, ZeroConf.fail, "ZeroConf", "register", [type, name, port, text]);
}
unregister: function() {
    return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unregister", [])
},
fail: function (o) {
    console.error("Error " + JSON.stringify(o));
}
}

config.xml

<plugins>
    <plugin name="ZeroConf" value="com.triggertrap.ZeroConf"/>
</plugins>

现在我的问题:

我想调用一个固定的URL,例如index.html页面中的http://foo.local/abc/,它应该解析为本地IP地址。我如何实现这一目标?我知道它必须使用 JavaScript 来完成,但是如何去做呢?我搜索了很多文章并到达这里。如果您能进一步指导我,我将不胜感激。

【问题讨论】:

标签: android cordova phonegap-plugins zeroconf


【解决方案1】:

在您收到“设备就绪”事件后的某个地方,您可以注册以观看通过 bonjour 宣传的服务:

ZeroConf.watch("_http._tcp.local.", function (service) { // do something with the service }

但是,使用 ZeroConf 插件是不够的,因为您还需要在 foo.local 提供内容的服务器通过 bonjour 宣传其 HTTP 服务。如果你使用 node.js 服务器,你可以使用这个module

【讨论】:

  • foo 是本地 LAN 网络上的设备名称。我正在尝试通过此 URL 访问该设备。
  • 您使用什么服务器技术在 foo 上提供网页服务?
  • 如果您已经在应用程序中硬编码了 foo.local,那么您正在寻找的功能是多播名称解析 mDNS(例如,将 foo.local 映射到 IP 地址)。 ZeroConf 插件提供 DNS 服务发现,并不是 mDNS 的直接替代品。您可能想查看 JmDNS 提供的完整 API,并仅使用 mDNS 部分(如果存在)。
  • Stribu: foo 实际上是一个硬件设备 arduino,这个应用程序基本上是为了尝试通过这个固定的应用程序 ping arduino网址。
  • 如何在您的 arduino 上使用它来宣传服务:forum.pjrc.com/threads/24481-ZeroConf-Bonjour-Library
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
相关资源
最近更新 更多