Android網(wǎng)絡(luò)服務(wù)發(fā)現(xiàn)(NSD)使用
NSD(NsdManager)是Android SDK中自帶的類庫,可以集成直接使用。
使用 NSD服務(wù)需要(android4.1及以上) minSdkVersion >16
通常應(yīng)用于局域網(wǎng)內(nèi)不同應(yīng)用設(shè)備的互聯(lián).
Nsd的兩個功能
- Nsd 注冊功能:
進行Nsd注冊:自定義服務(wù)名、端口號,IP地址注冊到Nsd服務(wù)中 - Nsd 掃描功能:
掃描到當前局域網(wǎng)內(nèi)所有已通過NSD注冊了的應(yīng)用設(shè)備的網(wǎng)絡(luò)信息(服務(wù)名、端口號、IP地址)
Nsd服務(wù)端
步驟
- NsdManager初始化
nsdManager = (NsdManager) getSystemService(NSD_SERVICE);
- 創(chuàng)建一個server來獲取端口
try {
mServerSocket = new ServerSocket(0);//設(shè)為0,會自動獲取沒有占用的端口
mPort = mServerSocket.getLocalPort();
} catch (IOException e) {
e.printStackTrace();
}
- 創(chuàng)建NsdServiceInfo
mNsdServiceInfo = new NsdServiceInfo();
mNsdServiceInfo.setServiceName(SERVICE_NAME);
mNsdServiceInfo.setServiceType(SERVICE_TYPE);
mNsdServiceInfo.setPort(mPort);
- 創(chuàng)建注冊監(jiān)聽
private void createRegistration() {
mRegistrationListener = new NsdManager.RegistrationListener() {
@Override
public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onRegistrationFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onUnregistrationFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceRegistered", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceUnregistered", Toast.LENGTH_SHORT).show();
}
};
}
- 注冊
mNsdManager = (NsdManager) getSystemService(NSD_SERVICE);
mNsdManager.registerService(mNsdServiceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
第2步創(chuàng)建NsdServiceInfo,調(diào)用各種set方法,是為了給客戶端信息,客戶端通過get方法可以拿到相應(yīng)的信息。
第4步注冊中的NsdManager.PROTOCOL_DNS_SD是基于Dns的服務(wù)發(fā)現(xiàn)協(xié)議。
Nsd客戶端
步驟
-
NsdManager初始化nsdManager = (NsdManager) getSystemService(NSD_SERVICE); - 創(chuàng)建兩個監(jiān)聽器。分別是
ResolveListener和DiscoveryListener分別來監(jiān)聽NsdServiceInfo的信息和服務(wù)的鏈接成功和失敗。
private void createResolverListener() {
mResolverListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onResolveFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
mNsdServiceInfo = nsdServiceInfo;
}
};
}
private void createDiscoverListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onStartDiscoveryFailed(String s, int i) {
Toast.makeText(MainActivity.this, "onStartDiscoveryFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onStopDiscoveryFailed(String s, int i) {
Toast.makeText(MainActivity.this, "onStopDiscoveryFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onDiscoveryStarted(String s) {
Toast.makeText(MainActivity.this, "onDiscoveryStarted", Toast.LENGTH_SHORT).show();
}
@Override
public void onDiscoveryStopped(String s) {
Toast.makeText(MainActivity.this, "onDiscoveryStopped", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
mmNsdServiceInfo = nsdServiceInfo;
//這里的nsdServiceInfo只能獲取到名字,ip和端口都不能獲取到,要想獲取到需要調(diào)用NsdManager.resolveService方法
Toast.makeText(MainActivity.this, "onServiceFound", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceLost", Toast.LENGTH_SHORT).show();
}
};
}
DiscoveryListener這個監(jiān)聽中的NsdServiceInfo只能獲取到名字,ip和端口都不能獲取到,要想獲取到需要調(diào)用NsdManager.resolveService方法。
- 發(fā)現(xiàn)周邊的NSD相關(guān)網(wǎng)絡(luò)
nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
第一個參數(shù)要和NSD服務(wù)器端定的ServerType一樣.
第二個參數(shù)是固定的
第三個參數(shù)是掃描監(jiān)聽器
- 主動調(diào)用resolveService方法
nsdManager.resolveService(mmNsdServiceInfo, mResolverListener);
主動調(diào)用該方法,會觸發(fā)
ResolveListener(),從而獲取到NsdServiceInfo信息。
- 需要停止時調(diào)用
nsdManager.stopServiceDiscovery(mDiscoveryListener);