问题是:我正在制作一个离线多人Android游戏,人们可以创建或加入一个房间,通过Wi-Fi一起玩。考虑用户创建一个房间时的情况,他(当然)必须通知所有其他用户有可用的房间。所以问题是“怎么做?”。我已经读了大约1000遍this
和this。
这里写的是,为了将一些数据发送到另一台设备,其中一台应该是服务器,另一台是客户机。客户端向服务器发送一些信息,服务器接受它。那么,这是否意味着我必须让所有的“玩家”服务器和“房间创建者”应该成为一个客户端?听起来很疯狂。请帮忙,我可能看错了文件?
最佳答案
首先,你需要记住,如果你决定在你的项目中使用WiFiP2P
,你需要为一些困难的时间做好准备。不幸的是(你可能已经注意到了:)WiFiP2P
Android的官方文档并没有那么好。不同的设备以不同的方式运行(例如,它们以不同的顺序调用某些WifiP2P
事件),文档根本不覆盖它。要实现稳定的连接,需要采取非常规的、有时甚至是极端的措施。获取WifiP2P
连接与显示系统窗口(询问是否真的要连接到设备)是不可分割的。
在开始实施WifiP2P
解决方案之前,您需要考虑以下几点:
您的游戏玩家是否可以同时连接到多个房间?
您的游戏玩家在连接到另一个房间时是否能够检测到新房间?
你的游戏玩家能用“人类可读”的名字命名他们的房间吗?其他用户(而不是文件室的创建者)将使用这些名称来选择要连接到的文件室?
场景A:
如果你对问题1回答“是”。或者2.如果你真的想使用WifiP2P
,你需要认真考虑。WifiP2P
(android的Wifi-Direct
实现)并不能真正满足您的需求。
使用WifiP2P
可能意味着房间所有者创建了一个WifiP2P-group
,任何想要加入房间的人都必须连接到这个WifiP2p-group
。
问题是android不允许单个设备同时加入多个组(这也意味着它不允许同时创建多个组)。检测周围可用WiFiP2P
设备中的更改也有问题(当您已连接到设备时)。
如果您真的想使用Wifi-Direct
,您可能需要使用一个WiFiP2P-group
并将所有设备连接到它。这个组就像一个普通的网络,所有与游戏室相关的东西都必须由一个节点作为一个典型的服务器来管理(或者可能不是一个典型的服务器,而是一些其他的网络解决方案)。
如果你真的不需要WifiP2P
使用常规Wifi
。将所有设备连接到一个网络(甚至可以在其中一个设备上启动一个热点),整个连接过程可以相对简单,在后台执行,而不需要用户直接参与。人可读的房间名称不是问题,因为您可以从服务器发送任何内容。
方案B:
如果你对问题3回答“是”。而且你真的需要使用WifiP2P
,你需要找到某种方式将你的“人类可读”名称广播到其他设备。
你可能认为这非常简单:连接到其他设备,说出你创建的房间的名称,就完成了。不是那么简单。如我之前所说:
获取WifiP2P
连接与显示系统窗口(询问是否确实要连接到设备)是不可分割的。
所以整个过程会更少:
设备A:启动与设备B的连接(该步骤也可以由设备B执行)
设备B:出现“丑陋的系统”窗口,询问您是否要连接到Android-ao12ij219sa
(一些程序上不可更改的系统设备名)
设备B:接受
设备B:正在等待连接结果
设备B:已连接,正在等待有关设备A的房间名称的信息
设备A:已连接,发送室名称
设备B:获取设备A的房间名称,正在断开连接(以后的连接请求也将导致显示系统窗口)
在执行步骤1-7时,没有其他设备可以连接到设备A(因此在此期间,没有其他设备可以获取房间的名称)。
可以做什么:
使用WifiP2P Service Discovery
。它允许广播一些信息,而无需获得连接。不幸的是,它的文档记录比WifiP2P
本身还要糟糕,而且它可能更不可靠(主观上)。如果你想在这个基础上做出一个可靠的解决方案,你需要花费数小时的时间来测试和寻找不同的情况下它可能不起作用。我从经验中知道这是可能的,但是需要从您那里实现一些变通方法,以便它始终能够获得稳定的WiFiP2P
连接。
发送到您的设备,这些(不可更改的)WifiP2P
名称和创建的房间名称之间的映射,以其他方式。例如通过你的服务器api或者其他什么…