我已经做了一些搜索,似乎没有太多成功的方法通过Coldfusion成功建立tcp / ip套接字连接.我正在尝试充当一个简单的客户端并发送一个字符串并获得响应. Adobe的EventGateway需要服务器端设置,我无法触摸,但也似乎只是一个监听器(根据Adobe的文档,“它可以向现有客户端发送传出消息,但不能自己建立链接.”).
在SO / cflib.org上有另一个例子,它是通过Web调用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()的发送,但是同样的行为.任何帮助将不胜感激.谢谢!
最佳答案 即使利用Java,这也是在ColdFusion中实现的一个非常具有挑战性的过程,原因很简单:
套接字通信是实时的,而Web请求具有有限的起始和停止点.
例如,当您发出ColdFusion模板请求时,所有内容(变量,共享内存,对象实例化等)都存在于页面请求的上下文中 – 并且(除了一些警告)在页面请求结束时死亡.所以,让我们假设您有一个CFML模板,在请求时执行以下任务:
>打开一个插座.
>建立与远程ip:端口的连接.
>听了回复.
>打印回复浏览器.
让我们进一步假设您的代码是正常运行,测试和工作的.您可以打开套接字,连接到远程IP和端口(您实际上看到远程服务器上的传入请求,并且可以确认这一点),并且出于所有意图和目的……您的连接很好.
然后,在您执行CFML页面10分钟后,远程服务器通过连接发送了一串文本…
…你的CFML端没有任何东西存活并等待响应,准备将其打印到浏览器.当CFML模板请求结束时,您实例化的对象,用于打开套接字和连接……都已消失.
这就是为什么(如上所述)当您尝试“读取响应”时,您发现该页面从未加载过.发生的事情是,ColdFusion被告知“请等待,我们实际上可能可能通过此套接字获取一些数据”…因此它阻止了Web请求结束并等待……这表明用户看起来像是一个“挂”的网页.
实时套接字通信的本质是连接和监听,等待响应……不幸的是,正在运行的网页无法永远运行(并“等待”),最终会超时.
最重要的是,虽然Java允许您打开/连接/发送/接收/关闭原始套接字,但是在CFML页面的上下文中这样做可能不是您最终要寻找的方法.