5

我用 Java 编写了 Socket 通信服务器,用 AS3 编写了一个 AIR 程序,使用 Socket 连接。通过套接字连接的通信是通过 JSON 序列化完成的。

有时,如果在套接字上串起很长的 JSON,AS3 代码会说存在 JSON 解析错误。

我以结束字符串结尾的每个 JSON 字符串让程序知道它不是消息的结尾,因此这不是 AIR 程序部分读取消息的问题。

该错误仅发生在非常长的 json 字符串中,例如长度为 78031 的字符串。JSON序列化有什么限制吗?

4

2 回答 2

1

我有同样的问题。问题在于 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
    }
}
于 2013-10-29T12:33:48.520 回答
0

根据 Adob​​e的说法,您似乎没有遇到 JSON 问题,而是遇到了 Socket 限制。

您可以通过 writeUTF 和 readUTF 通过 Socket 发送的字符串受 65,535 个字节的限制。这是因为字符串前面带有一个 16 位无符号整数,而不是一个以空字符结尾的字符串。

于 2013-08-14T02:56:51.313 回答