【问题标题】:What's the best way to share real-time GPS coordinates among a group?在群组之间共享实时 GPS 坐标的最佳方式是什么?
【发布时间】:2011-03-11 23:14:55
【问题描述】:

我正在设计一款游戏,要求玩家实时(接近)实时了解其他玩家的 GPS 真实世界位置。可能会有约 5 秒的延迟,但仍能正常运行。

目标平台是 Android,但是我对我的 iPhone 朋友很感兴趣,所以我希望使用 HTML5、Javascript 和 PHP 在网络上构建它。

我尝试了几种不同的方法,例如 BeaconPush 和不断地读取/写入 MySQL 数据库,但我不确定最佳和最有效的方法。我开始编写一堆代码,然后发现一个问题并尝试另一条路线,似乎一直在撞我的头。

游戏有点像吃豆人。三名球员正试图“抓住”一名球员。一个玩家在现实世界的地图上有一个特定的目标。游戏从数据库中获取坐标并将对象/图标生成到谷歌地图上。使用 navigator.geolocation.watchPosition 游戏检查物品的命中检测,玩家可以在物品经过时拾取物品。所有这些都可以正常工作,但地图必须能够在对象图标被移除时更新它们,并使用其他玩家的位置近乎实时地更新图标。我不确定如何以最有效的方式分享每个人的 GPS 位置。整个游戏基本上运行正常,除了这个(尽管是巨大的)拼图。

感谢您的指导!

【问题讨论】:

  • 考虑到大多数 GPS 设备都不是很精确(~ 20m),你需要一个很大的地方来玩这个,对吧?
  • 即使使用 WiFi,我也不希望在 5 秒内从设备同步到数据库到其他设备。听起来对我来说是高估了。祝你好运。
  • @NullUserException 是的,这是一个全市范围的游戏;碰撞检测目前设置为四分之一英里。 @M'vy 这就是我所担心的......我希望找到考虑到技术的最佳折衷方案,看看它是否会起作用。
  • 别告诉我你需要一辆车才能玩这个。关于技术,你在服务器端使用什么几乎不会是一个因素。用 MySQL/PHP 试一试,看看它是如何工作的。如果速度太慢,我会在具有更好带宽/延迟(或更好的手机/运营商)的服务器上投入更多资金。
  • 是的,我们的想法是为每辆汽车(2 对)配备一名司机和一名乘客/操作员,并将手机由汽车供电,并将显示器设置为永不关闭,以便始终保持 GPS 数据被发送。使用 coords.speed 限制游戏的速度。游戏是基于策略的(设置陷阱,使用小路),所以安全不是问题,因为鲁莽驾驶不会给你带来任何好处。我更担心汽油价格和共享 GPS 数据!

标签: php javascript mysql mobile gps


【解决方案1】:

好的,所以您的问题是如何在一个服务器和多个客户端之间进行近乎实时的有效通信。你有两个问题,与客户的有效沟通。以及服务器上“会话”之间的有效通信。

HTTP 客户端到服务器

http 协议是无状态的。这意味着您发送服务器响应的请求,然后连接关闭。这使得很难像游戏需求那样以双向或事件驱动的方式进行通信。这就是为什么大多数网络游戏使用 UDP 发送信息的开销要少得多。 我们必须使用 TCP/IP,并且在这种情况下我们必须使用 HTTP 协议,那么我们如何才能有效地做到这一点呢?

彗星就是答案。 Comet 服务器只是一个“术语”,它意味着一个服务器可以长时间保持连接打开以不断向客户端发送数据。 Comet 服务器使用异步流 (ajax) 连接,允许客户端“知道”新信息何时到达,而无需读取整个响应。 另请参阅:长轮询 PHP Comet Server

会话到会话

当服务器收到一个请求时,它需要问“其他人在哪里”这个问题,并且需要经常有效地问这个问题。 对于这样的事情,Mysql 不会是最好的技术解决方案。您想从多个进程(每个 http 客户端)非常非常快速地写入和读取小值

为什么要通过网络连接发送数据,将其解码为字符串 (sql),然后等待服务器解码插入或响应等 - 这听起来像是很多额外的开销。

您需要的是真正的 IPC(进程间通信)。这在 PHP 中很难实现,但可以做到。使用共享内存,甚至写入内存映射文件将是最高读取和写入 GPS 坐标更新率的最佳解决方案。 PHP IPC

把它绑在一起:

客户端向服务器发送请求并开始轮询它。服务器读取共享内存以查看其他人的坐标。服务器向打开的连接写入一行,其中包含描述所有玩家位置的 JSON 字符串。 同时,当客户端轮询服务器时,它还必须向服务器发送描述其位置的请求,并且服务器必须将此值写入共享内存。 程序会一直循环,直到客户端关闭 http 连接。

查看这些:

如果共享内存不是一个选项,那么我建议使用不同的数据库或更简单的东西,例如键值存储(memcache)甚至 mongodb。它们都将具有更少的事务开销,并且能够比 MySQL 更快地插入和轮询

第三种选择是使用 PostgreSQL 作为 IPC 机制。您可以为此使用 LISTEN 事件 - 但这有点做作。

注意事项:

此解决方案无法很好地与 PHP 一起扩展。假设您正在使用 apache,并且您的工作人员池中有 20 个工作人员。当您达到 20 个连接时,所有服务器的 php 进程都将被其他请求消耗,因此第 21 个请求将无休止地等待工作人员可用。

最好的解决方案是在 Twisted 或任何其他异步框架中实现 Comet 服务器/长轮询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-26
    • 2013-04-26
    • 2017-03-23
    • 2010-09-20
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多