Я разрабатываю многопользовательскую игру, использующую локальную сеть. Я использую фреймворк libgdx. Теперь я пытаюсь найти свою игру в локальной сети с помощью Android Nsd. Я не могу найти сервис в локальной сети, используя этот метод. Пожалуйста, помогите мне найти проблему или дайте мне совет, какой еще метод подключения я могу использовать? (я выбираю nsd, потому что мне не нужно много разрешений, и они нормальные, следующий вариант, который я вижу, — это Wi-Fi Direct, но он требует больше усилий)
Я могу найти сервис на машина, на которой работает мой код, но я не могу найти сервис на другой машине с тем же кодом, запущенным в той же локальной сети, на том же ssid. Мои телефоны: Xiaomi Redmi Note 8 (30 API) и Xiaomi Redmi 9C NFC (29 API)
Как я использую Nsd
В лаунчере я создаю реализации и даю им контекст для получения NsdManager.
На экране я указываю имя и порт для serverRegistration, чтобы использовать их для регистрации сервера.
На screen#show() я регистрирую свой сервис и в цикле рендеринга после задержки (сейчас эта задержка 0 мс) однажды я начинаю обнаруживать и не могу получить услугу не с локального компьютера.
Когда я запускаю код, я открываю HostsScreen на обоих телефонах
Важные части моего кода
Манифест
Реализация ServerDiscovery
public class ServerDiscoveryImpl implements ServerDiscovery {
private static final String TAG = "discoveryService";
private final NsdManager nsdManager;
public ServerDiscoveryImpl(Context context){
nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
this.context = context;
}
NsdManager.DiscoveryListener discoveryListener;
Context context;
// WifiManager.MulticastLock lock;
boolean started;
@Override
public void startDiscovery() {
discoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onStartDiscoveryFailed(String s, int i) {
Log.e(TAG, "DiscoveryStartFailed");
nsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String s, int i) {
Log.e(TAG, "StopDiscoveryFailed");
nsdManager.stopServiceDiscovery(this);
}
@Override
public void onDiscoveryStarted(String s) {
Log.d(TAG, "DiscoveryStarted");
}
@Override
public void onDiscoveryStopped(String s) {
Log.d(TAG, "DiscoveryStopped");
}
@Override
public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
System.out.println("omg, i found it");
NsdManager.ResolveListener resolveListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
Log.e(TAG, "resolve error");
}
@Override
public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
System.out.println(nsdServiceInfo.getServiceName()
+ " " + nsdServiceInfo.getServiceType()
+ " " + nsdServiceInfo.getHost().getHostAddress()
+ " " + nsdServiceInfo.getPort());
ServerInfo info = new ServerInfo(
new InetSocketAddress(nsdServiceInfo.getHost(), nsdServiceInfo.getPort()),
nsdServiceInfo.getServiceName()
);
servers.add(info);
}
};
nsdManager.resolveService(nsdServiceInfo, resolveListener);
}
@Override
public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
servers.remove(new ServerInfo(
new InetSocketAddress(nsdServiceInfo.getHost(), nsdServiceInfo.getPort()),
nsdServiceInfo.getServiceName()
));
}
};
// lock = ((WifiManager)context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock(TAG);
// lock.setReferenceCounted(true);
// lock.acquire();
nsdManager.discoverServices("_myApp._udp", NsdManager.PROTOCOL_DNS_SD, discoveryListener);
started = true;
}
@Override
public void endDiscovery() {
if(!started){
return;
}
started = false;
Log.d(TAG, "endDiscovery");
nsdManager.stopServiceDiscovery(discoveryListener);
// lock.release();
}
}
Реализация регистрации сервера
public class ServerRegistrationImpl implements ServerRegistration {
final private String TAG = "TTR Service registration";
final NsdManager manager;
InetSocketAddress address = null;
String name = null;
boolean started = false;
NsdManager.RegistrationListener registrationListener;
String actualName;
// WifiManager.MulticastLock lock;
Context context;
public ServerRegistrationImpl(Context context){
manager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
this.context = context;
}
@Override
public void register() {
if(address == null || name == null){
return;
}
registrationListener = new NsdManager.RegistrationListener() {
@Override
public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Log.e(TAG, "Service failed registration");
}
@Override
public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Log.e(TAG, "Service failed registration");
}
@Override
public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
actualName = nsdServiceInfo.getServiceName();
Log.d(TAG, "Service registered with name: " + actualName);
}
@Override
public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
Log.d(TAG, "Service unregistered");
}
};
NsdServiceInfo info = new NsdServiceInfo();
info.setServiceName(name);
info.setServiceType("_myApp._udp");
info.setPort(address.getPort());
// lock = ((WifiManager)context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock(TAG);
// lock.setReferenceCounted(true);
// lock.acquire();
manager.registerService(info, NsdManager.PROTOCOL_DNS_SD, registrationListener);
started = true;
}
@Override
public void unregister() {
if(!started){
return;
}
started = false;
manager.unregisterService(registrationListener);
// lock.release();
}
@Override
public void setAddress(InetSocketAddress address) {
this.address = address;
}
@Override
public void setName(String name) {
if(Objects.equals(name, "")){
return;
}
this.name = name;
}
}
AndroidLauncher
public class AndroidLauncher extends AndroidApplication {
private static final String TAG = "launcher";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
ServerDiscovery discovery = new ServerDiscoveryImpl(this);
ServerRegistration registration = new ServerRegistrationImpl(this);
initialize(new TimeToRun(discovery, registration), config);
}
}
HostScreen, экран, который я открываю на обоих телефонах, чтобы увидеть результаты
public class HostScreen extends ScreenAdapter {
TimeToRun game; // thing, that keeps implementations after making new instance and doesn't do with them anything
long time;
public HostScreen(TimeToRun game){
this.game = game;
}
@Override
public void show() {
time = TimeUtils.millis();
try {
socket = new DatagramSocket();
} catch (SocketException e) {
game.setScreenAndLoadNeededResources(TimeToRun.AppScreens.MENU);
return;
}
game.registration.setName(Gdx.app.getPreferences("social").getString("name"));
InetSocketAddress address = new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
game.registration.setAddress(address);
game.registration.register();
}
@Override
public void render(float delta) {
if(TimeUtils.millis() >= time && time != -1){
game.discovery.startDiscovery();
time = -1;
}
}
@Override
public void hide() {
game.registration.unregister();
game.discovery.endDiscovery();
}
}
Я ищу некоторые решения по переполнению стека, и ни задержка перед началом обнаружения, ни блокировка многоадресной рассылки Wi-Fi мне не помогли.
Log cat (неважно) что я делаю, на обоих устройствах)
2024-08-03 21:44:13.688 20269-20299 discoveryService com.timetorunclient.game D DiscoveryStarted
2024-08-03 21:44:14.329 20269-20299 TTR Servic...gistration com.timetorunclient.game D Service registered with name: anon659892
2024-08-03 21:44:14.579 20269-20299 System.out com.timetorunclient.game I omg, i found it
2024-08-03 21:44:14.594 20269-20299 System.out com.timetorunclient.game I anon659892 ._myApp._udp 192.168.0.181 38704
Подробнее здесь: https://stackoverflow.com/questions/788 ... ndroid-nsd
Я не могу найти сервис в локальной сети с помощью Android nsd ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение