Flex - XMLSocket усекает последний закрывающий тег XML - почему? - PullRequest
0 голосов
/ 02 марта 2010

У меня есть проект, который пытается отправить XML с помощью XMLSocket на сервер, который прослушивает его с другой стороны.

Файл приложения:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:Script>
                <![CDATA[
                        import MyConnection;

                        [Bindable]
                        public var conn:MyConnection = new MyConnection(33333);
                ]]>
        </mx:Script>
        <mx:VBox>
                <mx:Button label="Click me" buttonDown="conn.sendXml()" />
        </mx:VBox>
</mx:Application>

И MyConnection.as это:

package
{
 import flash.errors.*;
 import flash.events.*;
 import flash.net.XMLSocket;

 public class MyConnection  {

  private var hostName:String = "localhost";
        private var port:uint = 33333;
        private var socket:XMLSocket;
        private var xmlData:XML;


  public function MyConnection(port:int) {
   super();
   this.port = port;
   socket = new XMLSocket();
   configureListeners(socket);
  }  


  /**
   * @throws IOError 
   */
  public function sendXml():void {
   xmlData =
   <body>
    <action>Hello</action>
    <name>Kittie</name>
   </body>

   socket.connect(hostName, port);
  }

  /**
   * @param dispatcher IEventDispatcher
   */
  private function configureListeners(dispatcher:IEventDispatcher):void {
            dispatcher.addEventListener(Event.CLOSE, closeHandler);
            dispatcher.addEventListener(Event.CONNECT, connectHandler);
            dispatcher.addEventListener(DataEvent.DATA, dataHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        }

        private function closeHandler(event:Event):void {
            trace("closeHandler: " + event);
        }

        private function connectHandler(event:Event):void {
            trace("connectHandler: " + event);
            socket.send(xmlData);
   socket.close();
   xmlData = null;
        }

        private function dataHandler(event:DataEvent):void {
            trace("dataHandler: " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }

        private function securityErrorHandler(event:SecurityErrorEvent):void {
            trace("securityErrorHandler: " + event);
        }
 }
}

Как вы, вероятно, видите, это очень похоже на пример XMLSocket в справочнике по языку.

Однако, анализируя данные, полученные сервером, я получаю усеченный XML без закрывающего тега

Got connection from 127.0.0.1
<body>
  <action>Hello</action>
  <name>Kittie</name>
127.0.0.1 disconnected

И закрывающий тег появится при следующей отправке данных, т.е.

Got connection from 127.0.0.1
</body><body>
  <action>Hello</action>
  <name>Kittie</name>
127.0.0.1 disconnected

Есть идеи, почему это происходит? Есть предложения?

Я должен открывать и закрывать сокет при каждом запросе, но даже попытка не делать этого ради тестирования не помогла

Спасибо!

karnaf

1 Ответ

1 голос
/ 03 марта 2010

Я могу ошибаться в вашем конкретном случае, но при работе с соединениями Socket в целом ваш сервер должен быть настроен на получение пакетов, которые могут быть разделены. Например, если ваши данные длиннее, чем может содержать пакет, следующий пакет будет продолжением предыдущего обмена.

Это наиболее очевидно видно при просмотре необработанных сокетов в Wireshark, вы можете видеть пакеты продолжения TCP.

Я также заметил, что вы используете E4X для определения своего XML, возможно, вы захотите правильно завершить определение:

xmlData = <body>
 <action>Hello</action>
 <name>Kittie</name>
</body>;

И вызвать его с помощью функции toXMLString:

socket.send(xmlData.toXMLString());
...