我用 Java 编写了 Socket 通信服务器,用 AS3 编写了一个 AIR 程序,使用 Socket 连接。通过套接字连接的通信是通过 JSON 序列化完成的。
有时,如果在套接字上串起很长的 JSON,AS3 代码会说存在 JSON 解析错误。
我以结束字符串结尾的每个 JSON 字符串让程序知道它不是消息的结尾,因此这不是 AIR 程序部分读取消息的问题。
该错误仅发生在非常长的 json 字符串中,例如长度为 78031 的字符串。JSON序列化有什么限制吗?
我用 Java 编写了 Socket 通信服务器,用 AS3 编写了一个 AIR 程序,使用 Socket 连接。通过套接字连接的通信是通过 JSON 序列化完成的。
有时,如果在套接字上串起很长的 JSON,AS3 代码会说存在 JSON 解析错误。
我以结束字符串结尾的每个 JSON 字符串让程序知道它不是消息的结尾,因此这不是 AIR 程序部分读取消息的问题。
该错误仅发生在非常长的 json 字符串中,例如长度为 78031 的字符串。JSON序列化有什么限制吗?
我有同样的问题。问题在于 Flash 应用程序从套接字读取数据。
关键是即使服务器没有发送所有数据,Flash ProgressEvent.SOCKET_DATA 事件也会触发,并且会留下一些东西(特别是当数据很大并且连接很慢时)。所以像{"key":"value"}这样的东西有两个(或更多)部分,比如:{"key":"val and ue"}。此外,有时您可能会在一条消息中收到多个连接的 JSON,例如{"json1key":"value"}{"json2key":"value"} - 内置 Flash JSON 解析器也无法处理这些。
为了解决这个问题,我建议您修改 Flash 应用程序中的 SocketData 处理程序,为接收到的字符串添加缓存。像这样:
// declaring vars
private var _socket:Socket;
private var _cache: String = "";
// adding EventListener
_socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
private function onSocketData(e: Event):void
{
// take the incoming data from socket
var fromServer: ByteArray = new ByteArray;
while (_socket.bytesAvailable)
{
_socket.readBytes(fromServer);
}
var receivedToString: String = fromServer.toString();
_cache += receivedToString;
if (receivedToString.length == 0) return; // nothing to parse
// convert that long string to the Vector of JSONs
// here is very small and not fail-safe alghoritm of detecting separate JSONs in one long String
var jsonPart: String = "";
var jsonVector: Vector.<String> = new Vector.<String>;
var bracketsCount: int = 0;
var endOfLastJson: int = 0;
for (var i: int = 0; i < _cache.length; i++)
{
if (_cache.charAt(i) == "{") bracketsCount += 1;
if (bracketsCount > 0) jsonPart = jsonPart.concat(_cache.charAt(i));
if (_cache.charAt(i) == "}")
{
bracketsCount -= 1;
if (bracketsCount == 0)
{
jsonVector.push(jsonPart);
jsonPart = "";
endOfLastJson = i;
}
}
}
// removing part that isn't needed anymore
if (jsonVector.length > 0)
{
_cache = _cache.substr(endOfLastJson + 1);
}
for each (var part: String in jsonVector)
{
trace("RECEIVED: " + part); // voila! here is the full received JSON
}
}
根据 Adobe的说法,您似乎没有遇到 JSON 问题,而是遇到了 Socket 限制。
您可以通过 writeUTF 和 readUTF 通过 Socket 发送的字符串受 65,535 个字节的限制。这是因为字符串前面带有一个 16 位无符号整数,而不是一个以空字符结尾的字符串。