我有一个类Message,当数据通过网络时可以序列化,我目前使用JSON,主要是因为我使用JSON来处理所有事情。 (网络服务,套接字)。
我想改进序列化以使其尽可能好,我相信这里的改进是可能的。
目的是使传输字符串更轻,特别是在套接字(视频游戏)使用时,因为它将用于所有,每个响应客户端/服务器或服务器/客户端,甚至内部服务器或客户端方法,这是提供数据的常用方法。
Message是一个复杂的对象,它也可以包含其他对象实例,比如MessageLang,它将负责根据代码在客户端上翻译句子。
到目前为止它工作正常,结果如下:
套接字服务器使用简单字符串发出:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["Respond to emitter"]}
套接字服务器使用简单的消息实例发出:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["{\"m\":\"Respond to all clients\",\"d\":{},\"s\":1,\"t\":\"m\"}"]}
套接字服务器发出复杂的消息实例:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["{\"m\":{\"m\":\"__12\",\"a\":{\"field\":\"name\",\"min\":3,\"max\":20}},\"d\":{\"key\":\"fakeKey\"},\"s\":1,\"t\":\"m\"}"]}
复合信息将呈现以下句子:
名称的最小长度为3.最大长度为20。并且key: "fakeKey"
中包含data
。只是为了解释它是如何工作的。
如您所见,消息变得越来越大并且这是正常的,但我想知道我可以做些什么来在这里进行更好的序列化:
\
,因为它是JSON,我相信这是一个问题,因为每次我添加一些东西我都会得到额外的字符我不想。也许JSON不是一个好的选择,我应该以不同的方式序列化,首先是JSON,如顶部的例子,但接着是其他东西,也许是二进制,如果占用的空间更少。您怎么看?
如果以某种方式加密以其他格式显示消息是个好主意,那么加密的成本是否值得呢?因为加密它也需要一点时间,所以我只是想知道它是否不会只是移动问题,就像通过套接字发送消息需要更少的时间,因为它会更轻,但我们会使用更多时间加密它。只是想知道。
答案 0 :(得分:2)
我的猜测是,您的邮件对象有两个字段(name
和args
)。
减少消息长度的第一站是摆脱(相当无用的)外部对象并用数组替换它。所以一条空信息
{"name":"empty","args":[]}
会变成
["empty",[]]
甚至
["empty"]
接下来就是你在参数序列化中有一个错误。您可以将JSON数据包装在字符串中,而不是发送JSON。示例:在经过身份验证的情况下,您发送
{"name":"user.newAuthenticated","args":["{\"m\":\"Respond to all clients\",\"d\":{},\"s\":1,\"t\":\"m\"}"]}
但你应该发送
{"name":"user.newAuthenticated","args":[{"m":"Respond to all clients","d":{},"s":1,"t":"m"}]}
代替。现在的问题是args是否是单个对象的列表。如果它总是一个对象,那么你也可以摆脱[]
。根据我上面的建议更改,这会给你:
["user.newAuthenticated",{"m":"Respond to all clients","d":{},"s":1,"t":"m"}]
这是相当不错的IMO。如果可以使(de-)序列化程序正确处理默认值,则可以将其减少为:
["user.newAuthenticated",{"m":"Respond to all clients","s":1,"t":"m"}]
(即我们可以省略空d
属性)。
答案 1 :(得分:1)
对于MMO,我认为必须将最少的数据发送给客户端。如果套接字被称为2xx / 3xx秒,则必须尽可能减少通过套接字发送的数据的大小。
另一方面,它也消耗了资源来加密服务器端的对象以发送对象的缩小版本...最好不要减少它并发送一个没有减少的对象,所以我们不要花了资源加密它?