Простое соединение через сокет TCP / IP с использованием ColdFusion - PullRequest
4 голосов
/ 12 января 2012

Я провел некоторый поиск, и похоже, что успех в установлении соединения через tcp / ip socket через Coldfusion невелик. Я пытаюсь действовать как простой клиент, отправляю строку и получаю ответ. Для Adobe EventGateway требуется настройка на стороне сервера, к которой я не могу прикоснуться, но, похоже, это только слушатель (согласно документу Adobe: «Он может отправлять исходящие сообщения существующим клиентам, но не может установить ссылку сам».).

Есть еще один пример на SO / cflib.org, который является преобладающим в Интернете постом, в котором вызываются объекты Java, но я не справляюсь с этим, и, похоже, у всех остальных есть какие-то проблемы с этим. В моих попытках я могу заставить его инициализировать / подключить сокет, но больше ничего. Если я пытаюсь отправить строку, страница CF загружается нормально, но серверная сторона, похоже, никогда ничего не видит (но регистрирует или отмечает подключение / отключение). Если я попытаюсь прочитать ответ, страница никогда не загрузится. Если я закрою сервер, пока он пытается, он покажет сброс соединения при попытке readLine (). Я пробовал это с собственным приложением, а также с простым прослушивателем сокетов Java, который отправит сообщение при подключении и должен повторить все отправленные сообщения.

Разве это не работа для CF? Если нет, то какие-нибудь другие простые предложения / примеры из области jQuery / Ajax?

Приложение для прослушивания Java:

package blah;

import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

import java.io.*;
import java.net.*;

class SocketServer extends JFrame
    implements ActionListener {

/**
 * 
 */
private static final long serialVersionUID = 1L;
JButton button;
   JLabel label = new JLabel("Text received over socket:");
   JPanel panel;
   JTextArea textArea = new JTextArea();
   ServerSocket server = null;
   Socket client = null;
   BufferedReader in = null;
   PrintWriter out = null;
   String line;

   SocketServer(){ //Begin Constructor
     button = new JButton("Click Me");
     button.addActionListener(this);

     panel = new JPanel();
     panel.setLayout(new BorderLayout());
     panel.setBackground(Color.white);
     getContentPane().add(panel);
     panel.add("North", label);
     panel.add("Center", textArea);
     panel.add("South", button);

   } //End Constructor

  public void actionPerformed(ActionEvent event) {
     Object source = event.getSource();

     if(source == button){
         textArea.setText(line);
     }
  }

  public void listenSocket(){

    try{
      server = new ServerSocket(4444); 
    } catch (IOException e) {
     System.out.println("Could not listen on port 4444");
      System.exit(-1);
    }

    try{
      client = server.accept();
 //Show connection status in text box, and send back to client
      line = " Connected ";
      out.println(line);
      textArea.setText(line);
    } catch (IOException e) {
      System.out.println("Accept failed: 4444");
      System.exit(-1);
    }

    try{
      in = new BufferedReader(new InputStreamReader(client.getInputStream()));
      out = new PrintWriter(client.getOutputStream(), true);
    } catch (IOException e) {
      System.out.println("Accept failed: 4444");
      System.exit(-1);
    }

    while(true){
      try{
//Try to concatenate to see if line is being changed and we're just not seeing it, show in textbox
        line = line + " " + in.readLine();
        textArea.setText(line);
//Send data back to client
        out.println(line);
      } catch (IOException e) {
        System.out.println("Read failed");
        System.exit(-1);
      }
    }
  }

  protected void finalize(){
//Clean up 
     try{
        in.close();
        out.close();
        server.close();
    } catch (IOException e) {
        System.out.println("Could not close.");
        System.exit(-1);
    }
  }

  public static void main(String[] args){
        SocketServer frame = new SocketServer();
    frame.setTitle("Server Program");
        WindowListener l = new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                        System.exit(0);
                }
        };
        frame.addWindowListener(l);
        frame.pack();
        frame.setVisible(true);
    frame.listenSocket();
  }
}

CF Простая отправка (за исключением HTML-заголовка / нижнего колонтитула, IP-адрес должен быть жестко закодирован, порт на простом слушателе = 4444):

<cfset sock = createObject( "java", "java.net.Socket" )>
<cfset sock.init( "ip.ip.ip.ip", 4444)>

<cfset streamOut = sock.getOutputStream()>

<cfset output = createObject("java", "java.io.PrintWriter").init(streamOut)>
<cfset streamOut.flush()>

<cfset output.println("Test Me")>
<cfset output.println()>

<cfset streamOut.flush()>

<cfset sock.shutdownOutput()>
<cfset sock.close()>

Простое чтение CF (опять же, минус шаблон заголовка / нижнего колонтитула, IP-адрес сервера, который будет жестко задан, порт 4444)

<cfset sock = createObject( "java", "java.net.Socket" )>
<cfset sock.init( "ip.ip.ip.ip", 4444)>

<cfset streamInput = sock.getInputStream()>
<cfset inputStreamReader= createObject( "java", "java.io.InputStreamReader").init(streamInput)>

<cfset input = createObject( "java", "java.io.BufferedReader").init(InputStreamReader)>

<cfset result = input.readLine()>

<cfset sock.shutdownInput()>
<cfset sock.close()>

Я попытался добавить некоторые спящие здесь и там, а также попытался отправить, не используя PrintWriter / используя только ObjectOutputStream и writeObject (), но с тем же поведением. Любая помощь будет принята с благодарностью. Спасибо!

1 Ответ

2 голосов
/ 12 января 2012

Это будет очень сложный процесс для внедрения в ColdFusion, даже при использовании Java, по простой причине:

Обмен данными через сокет осуществляется в режиме реального времени, в то время как веб-запросыконечные точки запуска и остановки.

Например, когда вы делаете запрос шаблона ColdFusion, все (переменные, общая память, создание объектов и т. д.) живет в контексте запроса страницы - и(за исключением нескольких предостережений) умирает, когда заканчивается запрос страницы.Итак, давайте предположим, что на данный момент у вас есть шаблон CFML, который выполняет по запросу следующие задачи:

  1. Открыл сокет.
  2. Установил соединение с удаленным портом ip :.
  3. Прислушался к ответу.
  4. Распечатал этот ответ для браузера.

Предположим далее, что ваш код запущен, протестирован и работает,Вы можете открыть сокет, подключиться к удаленному ip и порту (вы на самом деле видите входящий запрос на удаленном сервере и можете подтвердить это) и для любых целей ... ваше соединение в порядке.

Затем, через 10 минут после того, как вы выполнили свою страницу CFML, удаленный сервер отправил текстовую строку по соединению ...

... на вашем конце CFML нет ничего, что является живым и ожидает этого ответа, готовый распечатать его в браузере.Объекты, которые вы создали, использовали для открытия сокета и подключения ... все ушли, когда закончился запрос шаблона CFML.

Вот почему (как указано выше), когда вы пытались "прочитатьответ ", вы заметили, что страница никогда не загружается.Происходит то, что ColdFusion говорят: «Пожалуйста, подождите, мы могли бы, возможно, получить некоторые данные через этот сокет» ... поэтому он блокирует завершение веб-запроса и ожидает ..., который отображается для пользователя как то, что кажетсябыть "зависшей" веб-страницей.

Природа сокетной связи в реальном времени заключается в том, что она подключена и слушает, ждет ответа ... и, к сожалению, работающая веб-страница не может работать (и «ждать») вечно, в конечном итоге она будетtimeout.

Суть в том, что хотя Java позволит вам открывать / подключать / отправлять / получать / закрывать необработанные сокеты, выполнение этого в контексте страницы CFML может не подходить вам в конечном итоге.для.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...