2014-02-12 4 views
8

Я пытаюсь построить сервер-клиентскую архитектуру, используя два устройства Android с одноранговым WiFi-соединением. У меня есть четкое различие между клиентом и сервером, поэтому я пытаюсь сократить ненужный код. Используя указания из http://developer.android.com/training/connect-devices-wirelessly/nsd-wifi-direct.html я получил ...Как получить одноранговое сервисное обслуживание Wi-Fi для работы?

PeerToPeerService

public class PeerToPeerService { 
    private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerService.class); 

    private WifiP2pManager mManager; 
    private WifiP2pManager.Channel mChannel; 
    private final Context mContext; 
    private final WifiP2pDnsSdServiceInfo mService; 

    public PeerToPeerService(Context context, String name) { 
     mContext = context; 

     Map<String, String> record = new HashMap<String, String>(); 
     record.put(Constants.SERVICE_PROPERTY_NAME, name); 
     record.put(Constants.SERVICE_PROPERTY_PORT, "12345"); 

     mService = WifiP2pDnsSdServiceInfo.newInstance(
       "_test", "_presence._tcp", record); 
    } 

    public void start() { 
     mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE); 
     mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); 

     mManager.addLocalService(mChannel, mService, new ActionListener() { 
      @Override 
      public void onSuccess() { 
       LOG.info("Started Service"); 
      } 

      @Override 
      public void onFailure(int error) { 
       LOG.warn("Failed to Start Service: {}", error); 
      } 
     }); 
    } 

    public void stop() { 
     mManager.removeLocalService(mChannel, mService, null); 
     mManager = null; 
     LOG.info("Stopped Service"); 
    } 
} 

PeerToPeerClient

public class PeerToPeerClient { 
    private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerClient.class); 

    private WifiP2pManager mManager; 
    private WifiP2pManager.Channel mChannel; 
    private final Context mContext; 

    public PeerToPeerClient(Context context) { 
     mContext = context; 
    } 

    public void findServices() { 
     mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE); 
     mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); 

     mManager.setDnsSdResponseListeners(mChannel, 
       new DnsSdServiceResponseListener() { 
        @Override 
        public void onDnsSdServiceAvailable(String instanceName, 
          String registrationType, WifiP2pDevice device) { 
         LOG.info("A"); 
         LOG.info("Service Found: {}:{}", instanceName, registrationType); 
        } 
       }, 
       new DnsSdTxtRecordListener() { 
        @Override 
        public void onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> record, 
          WifiP2pDevice device) { 
         LOG.info("B"); 
         LOG.info("{}:{} is {}", device.deviceName, 
           record.get(Constants.SERVICE_PROPERTY_PORT), record.get(Constants.SERVICE_PROPERTY_NAME)); 
        } 
       }); 

     WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance(); 
     mManager.addServiceRequest(mChannel, serviceRequest, 
       new ActionListener() { 
        @Override 
        public void onSuccess() { 
         LOG.info("Added service discovery request"); 
        } 

        @Override 
        public void onFailure(int error) { 
         LOG.info("Failed adding service discovery request: {}", error); 
        } 
       }); 

     mManager.discoverServices(mChannel, new ActionListener() { 
      @Override 
      public void onSuccess() { 
       LOG.info("Service discovery initiated"); 
      } 

      @Override 
      public void onFailure(int arg0) { 
       LOG.info("Service discovery failed"); 
      } 
     }); 
    } 
} 

Каждый ActionListener имеет OnSuccess называется, без сбоев в любом месте. Но я никогда не получаю никаких обратных вызовов setDnsSdResponseListeners. Любые идеи, в которых я, возможно, ошиблась?

+0

Обратите внимание, что андроид пример демонстрирует это отлично работает у меня между устройствами. – Hounshell

ответ

5

У меня есть опыт работы с Wi-Fi Direct на устройствах Android, я пишу приложение для подключения устройств ad-hoc и общения в чате по этой ссылке.

Для обнаружения на Wi-Fi Direct оба устройства необходимо сканировать, т.е. mWifiP2pManager.discoverPeers(). Странно, это также влияет на открытие DnsTxtRecordServices. Таким образом, я нашел, что это работает, если вы запустите свой scanning(discoverPeers()) на обоих устройствах, а затем запустите discoverPeers().

Надеюсь, это поможет! :)

+0

вы можете посмотреть на этот вопрос 'http: // stackoverflow.com/ questions/28252866/inconsistency-in-getting-wifip2pinfo-in-wifidirect' – Hunt

+0

« Чтобы быть видимым в Wi-Fi Direct, необходимо, чтобы оба устройства сканировались , ie.mWifiP2pManager.discoverPeers() «... Ты спас мой день! – Massimo

0

Я думаю, что вы пропустили некоторые моменты:

PeerToPeerService: код сервера

1. реализуют открытие клиентов

PeerToPeerClient: код клиента

1. реализовать addint клиента локальной службы

, которые будут обнаружены серверы

PeerToPeerService:

// after adding local service 
    manager.setDnsSdResponseListeners(channel, 
      new DnsSdServiceResponseListener() { 
      ... 
    } 

PeerToPeerClient:

mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); 
// add client local service 
mManager.addLocalService(mChannel, mService, new ActionListener() { 
      @Override 
      public void onSuccess() { 
       LOG.info("Started Service"); 
      } 

      @Override 
      public void onFailure(int error) { 
       LOG.warn("Failed to Start Service: {}", error); 
      } 
     }); 

После этого кода, вы будете в телефонном звоните onDnsSdResponseListener, и вы можете связаться

После подключения, вы можете проверить, если вы на стороне сервера или на стороне клиента с помощью WifiP2pInfo.isGroupOwner - верна для сервера и ложно для клиента

0

Для обоих клиента & сервера, вы должны вызвать addLocalService и discoverServices для WifiP2p в Работа.

Map record = new HashMap(); 
record.put("name","your_app_anme"); 

WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence.tcp", record); 
wifiP2pManager.addLocalService(wifiP2pChannel, serviceInfo, null); 


wifiP2pManager.setDnsSdResponseListeners(wifiP2pChannel, new WifiP2pManager.DnsSdServiceResponseListener() { 
    @Override 
    public void onDnsSdServiceAvailable(String s, String s1, WifiP2pDevice wifiP2pDevice) { 
     Log.wtf("WTF", "device "+wifiP2pDevice.deviceName + "/"+wifiP2pDevice.deviceAddress); 
    } 
}, new WifiP2pManager.DnsSdTxtRecordListener() { 
    @Override 
    public void onDnsSdTxtRecordAvailable(String s, Map<String, String> map, WifiP2pDevice wifiP2pDevice) { 
     Log.wtf("WTF", "got txt "+map.get("name")); 
    } 
}); 

WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance(); 
wifiP2pManager.addServiceRequest(wifiP2pChannel, serviceRequest, null); 
wifiP2pManager.discoverServices(wifiP2pChannel, null); 
0

После тонн попыток, я получил надежный работоспособный поток, как это:

... 
wifiP2pManager.clearLocalServices(wifiP2pChannel, new WifiP2pManager.ActionListener() { 
      @Override 
      public void onSuccess() { 
       HashMap<String, String> record = new HashMap<>(); 
       record.put("name", "Amos"); 
       WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance(AppConfig.DNS_SD_SERVICE_NAME, AppConfig.DNS_SD_SERVICE_TYPE, record); 
       wifiP2pManager.addLocalService(wifiP2pChannel, serviceInfo, new WifiP2pManager.ActionListener() { 
        @Override 
        public void onSuccess() { 
         wifiP2pManager.setDnsSdResponseListeners(wifiP2pChannel, WifiDirectFragment.this, WifiDirectFragment.this); 
         wifiP2pManager.clearServiceRequests(wifiP2pChannel, new WifiP2pManager.ActionListener() { 
          @Override 
          public void onSuccess() { 
           wifiP2pManager.addServiceRequest(wifiP2pChannel, WifiP2pDnsSdServiceRequest.newInstance(), new WifiP2pManager.ActionListener() { 
            @Override 
            public void onSuccess() { 
             wifiP2pManager.discoverPeers(wifiP2pChannel, new WifiP2pManager.ActionListener() { 
              @Override 
              public void onSuccess() { 
               wifiP2pManager.discoverServices(wifiP2pChannel, new WifiP2pManager.ActionListener() { 
                @Override 
                public void onSuccess() { 
                 // this is my recursive discovery approach                
                 handler.postDelayed(discoveryRunnable, AppConfig.DNS_SD_SERVICE_DISCOVERABLE_DURATION_S * 1000); 
                } 

                @Override 
                public void onFailure(int code) { 
                } 
               }); 
              } 

              @Override 
              public void onFailure(int code) { 
              } 
             }); 
            } 

            @Override 
            public void onFailure(int code) { 
            } 
           }); 
          } 

          @Override 
          public void onFailure(int code) { 
          } 
         }); 
        } 

        @Override 
        public void onFailure(int code) { 
        } 
       }); 
      } 

      @Override 
      public void onFailure(int code) { 
      } 
     });