我目前正在使用带有两台计算机(mac1和mac2)的objective-c进行某些模拟的客户端 - 客户端方法。
我有一个类Client,每台计算机上都有一个“Client”实例(client1,client2)。我希望两个客户端都会同步:它们将与内存位置相等。
当用户按下mac1上的某个键时,我希望client1和client2都接收来自Client类的给定方法(以便它们被同步,即它们与每个mac上的内存位置相同)。
对于这种方法,我目前的想法是制作两种方法:
- (void) sendSelector:(Client*)toClient,...;
- (void) receiveSelector:(Client*)fromClient,...;
sendSelector:使用NSStringFromSelector()将方法转换为NSString,并通过网络发送(现在不用担心通过网络发送字符串)。
另一方面,receiveSelector:使用NSSelectorFromString()将NSString转换回选择器。
我的第一个问题是:这种方法在与Objective-c联网的“标准”到什么程度?
我的第二个问题:
方法的论点?有没有办法“打包”给定的类实例并通过网络发送它?我理解指针在打包时的问题,但我的程序中的每个实例都是唯一的标识,所以这应该没有问题,因为两个客户端都知道如何从其标识中检索对象。
感谢您的帮助
答案 0 :(得分:1)
让我先解决你的第二个问题:
方法的论点?有没有办法“包装”一个给定的 类实例并通过网络发送它?
许多Cocoa类实现/采用NSCoding @protocol。这意味着它们支持一些默认实现,用于序列化为字节流,然后您可以通过网络发送。建议您使用NSCoding方法,除非由于某种原因它根本不适合您的需求。 (即使用最高级别的抽象来完成工作)
现在为你的第一个问题提供更多的哲学方面;我将你的问题改写为“使用序列化方法调用作为通过网络在两个客户端之间进行通信的手段是一种好方法吗?”
首先,您应该知道Objective-C有一个不经常使用的任何更多但相当完整的实现,用于处理具有高抽象级别的计算机之间的远程调用。它被称为分布式对象。 Apple似乎在某种程度上将它推到地毯下(有充分的理由 - 继续阅读),但我能够找到Distributed Objects Programming Topics指南的旧缓存副本。您可能会发现它内容丰富。 AFAIK,分布式对象的所有基础仍然存在于Objective-C运行时/框架中,因此如果您想使用它,如果只是原型,您可能可以。
我无法推测这些天你似乎无法在developer.apple.com上找到这份文件的确切原因,但我认为一般来说,你不想这样做是公平的在生产中使用这样的远程调用方法,或者在不安全的网络通道上使用(例如:通过Internet)。这是一个巨大的潜在攻击向量。试想一下:如果我可以修改或欺骗你的网络消息,我可以诱使你的客户端应用程序用任意参数调用任意选择器。不难看出这可能会如何非常错误。
在高层次上,让我建议为你的应用程序提出某种协议,使用一些任意的线格式(另一个人提到JSON - 这些天它得到了很多支持 - 但是使用NSCoding可能会引导你是最快的),当你的客户收到这样的消息时,它应该读取消息作为数据并决定采取什么行动,而不是在运行时实际导出什么是实际的<来自邮件本身的em> code 。
从“完成任务”的角度来看,我喜欢分享我前一段时间学到的一句格言:“让它工作;让它正常工作;让它快速工作。按顺序。”
对于原型设计,也许你不关心安全性。也许当你只是试图“让它工作”你使用分布式对象,或者你可能会推出自己的远程调用协议,因为它似乎一直在考虑做。请记住:在将其发布到野外之前,你真的需要“让它正常工作”,或者你为原型设计做出的决定可能会让你付出沉重的代价。这里最好的方法是创建一个类或一组类,从其余的代码中抽象出网络协议和有线格式,这样您就可以在以后更换网络实现而无需触及所有你的代码。
还有一个建议:我在你的初始问题中读到了“让一个对象(或者一个对象图)在多个客户端之间保持同步的愿望”。这是一个复杂的主题,但您可能希望使用“命令模式”(参见“四人帮”一书,或者在野外进行任何其他处理。)采用这种方法也可能固有地为您的网络协议带来结构。换句话说,一旦你将所有的模型变异操作分解为“命令”,你的协议可能就像使用NSCoding将这些命令序列化并通过网络传输到另一个客户端并在那里再次执行它们一样简单。
希望这有帮助,或者至少为您提供一些起点和要考虑的事项。
答案 1 :(得分:0)
现在似乎最标准的方法是将所有内容打包在JSON上。