草庐IT

objective-c - GameKit/互联网上的点对点

coder 2024-01-10 原文

对于我正在开发的 iOS 应用程序,我希望多部手机相互连接并能够在这些设备之间进行语音聊天。

当两个设备都在同一个网络上时,我可以正常工作。这非常简单,我想做的大部分事情都是可能的。

但是现在我要添加互联网支持,这很麻烦。我将首先尝试使用我设置的小型网络服务来解释我想要如何匹配设备。

服务器

  1. 使用 session 模式 GKSessionModePeer 开始一个新的 GameKit session
  2. 在我刚刚创建的 session 中找到服务器的“Peer ID”
  3. 在空闲端口上创建一个新的 CFSocketRef 并使其准备好接受连接
  4. 将对等 ID 和端口号发送到我在外部服务器上运行的网络服务。

网络服务

  1. Webservice 接收信息并将其与客户端的 ID 和 IP 地址一起存储在数据库中。
  2. 将ID发送回服务器,显示ID

客户端

  1. 当用户选择使用 GameKit 的“在线”功能来搜索游戏时,我会要求用户提供 ID(用户应在此处输入服务器收到的 ID)。
  2. 客户端连接到提供 ID 的网络服务。 Web 服务返回有关服务器 session 的信息(IP、端口、对等 ID)。
  3. 用户尝试使用端口信息连接到 IP 地址,并与服务器建立输入和输出流。

这当然行不通,因为我的网络不允许传入连接和随机端口(来自外部网络)。

但现在的问题是,我该如何解决呢?我希望能够在 2 台设备之间建立点对点连接,这些设备可以在同一网络上,也可以在不同的网络上。

是否有框架、示例或任何说明如何执行此操作的内容?我希望能够在设备之间发送数据,而无需先将其发送到服务器。

最佳答案

我不知道有任何框架可以做到这一点。不过,我在跨多个网络的 p2p 网络方面确实有很多经验。

我学到的一条重要规则:在网络之间通信时,不要创建直接连接,除非必要。有太多因素可以(将会?)导致问题,例如防火墙、NAT 等。

当然,你可以让连接先试。您可以尝试连接到给定的 IP 地址*,但在大多数情况下会失败。即使在使用 UPnP 和 NAT-PMP 时,您也会发现在很多情况下(超过一半?)您根本无法接受传入连接。

所以一定要有一个备用计划。制作一个网络层抽象,它不仅可以 listen(),还可以连接到服务器。这样,当您无法连接到客户端的 IPs* 时,您只需通过服务器设置连接,网络抽象就会处理这一切。

让我重申以上几点:不要只依赖传入连接,始终有一个备份计划。


* 我写 IP 是因为客户端可以有多个本地/远程 IP。连接时始终遍历所有这些 IP。示例:我的手机有 2 个本地 IPv4 地址(10.0.0.172 和 10.8.0.2)和一个 IPv6 地址([2001:x:x::6])。在这三个地址中,只有 IPv6 地址是公开可达的,而这两个 IPv4 地址位于不同的子网中,因此您是否可以连接到它们取决于另一个客户端所在的子网。始终尝试连接到两者,并在失败时回退到服务器代理连接。

** 我提到了 IPv6,是的。请不要忘记,与 IPv4 不同,IPv6 不受 NAT 的限制,这意味着如果支持的话,与 IPv4 相比,您更有可能通过 IPv6 获得良好的连接。

关于objective-c - GameKit/互联网上的点对点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14005162/

有关objective-c - GameKit/互联网上的点对点的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  4. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  5. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

  6. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  7. ruby object.hash - 2

    一个对象的散列值是什么意思?在什么情况下两个对象具有相同的哈希值??还有说Array|Hash不能是Hashkeys,这个跟对象的hash值有关系,为什么? 最佳答案 对于要存储在HashMap或哈希集中的对象,必须满足以下条件:如果认为两个对象相等,则它们的哈希值也必须相等。如果两个对象不被认为是相等的,那么它们的哈希值应该很可能不同(两个不同的对象具有相同哈希值的次数越多,对HashMap/集合的操作性能就越差)。因此,如果两个对象具有相同的哈希值,则很有可能(但不能保证)它们相等。上面“相等”的确切含义取决于散列方法的实现者。

  8. ruby - 为什么 Object 在 Ruby 中既包含内核又继承它? - 2

    在Ruby(1.8.X)中为什么Object既继承了内核又包含了内核?仅仅继承还不够吗?irb(main):006:0>Object.ancestors=>[Object,Kernel]irb(main):005:0>Object.included_modules=>[Kernel]irb(main):011:0>Object.superclass=>nil请注意,在Ruby1.9中情况类似(但更简洁):irb(main):001:0>Object.ancestors=>[Object,Kernel,BasicObject]irb(main):002:0>Object.included

  9. ruby-on-rails - Rails 3 : Looping through array of objects, 忽略数组中的第一个对象? - 2

    在我看来,我正在尝试显示一个对象表,这是我的代码:CategoriesCBB's">然而这是抛出一个错误说:can'tconvertCapabilityBuildingBlockintoArray关系是正确的,错误来self尝试在此处减去数组的第一个对象的行:有什么方法可以忽略数组中的第一个对象来遍历数组吗?谢谢 最佳答案 尝试使用Array.drop-http://www.ruby-doc.org/core/classes/Array.html#M000294 关于ruby-on-ra

  10. ruby-on-rails - my_object.save(false) 并没有真正跳过我的 Active Record 验证 - 2

    所以我一直在努力解决我一直遇到的这个错误,我终于找到了导致它的原因。我一直觉得,当我调用@my_model.save(false)我会跳过我的ActiveRecord验证。事实证明这是部分正确的。我的对象正在保存到数据库中DESPITE我的ActiveRecord验证。我的问题存在是因为我的一个验证在验证过程中修改了一个子模型(这是一个24小时位置的调度应用程序,因此当午餐被保存时,我对照他们保存的那天和第二天检查它们以及确保用户不是指“凌晨2点”表示要上夜类。我的问题是:有没有办法真正跳过我的验证并直接移动到数据库?这是正常的ActiveRecord行为还是我应该更深入地研究我的验证

随机推荐