Mule中的TCP服务器配置-写入客户端套接字
我正在尝试使用TCP入站端点创建mule流,该端点是侦听端口的TCP服务器。当识别成功的客户端连接时,在接收到来自客户端的任何请求之前,我需要将消息写入套接字(这会让客户端知道我正在侦听),之后客户端才会向我发送进一步的请求。下面是我如何使用示例java程序来实现这一点:Mule中的TCP服务器配置-写入客户端套接字,mule,Mule,我正在尝试使用TCP入站端点创建mule流,该端点是侦听端口的TCP服务器。当识别成功的客户端连接时,在接收到来自客户端的任何请求之前,我需要将消息写入套接字(这会让客户端知道我正在侦听),之后客户端才会向我发送进一步的请求。下面是我如何使用示例java程序来实现这一点: import java.net.*; import java.io.*; public class TCPServer { public static void main(String[] args) throws
import java.net.*;
import java.io.*;
public class TCPServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4445);
}
catch (IOException e)
{
System.err.println("Could not listen on port: 4445.");
System.exit(1);
}
Socket clientSocket = null;
System.out.println ("Waiting for connection.....");
try {
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
System.out.println ("Connection successful");
System.out.println ("Sending output message - .....");
//Sending a message to the client to indicate that the server is active
PrintStream pingStream = new PrintStream(clientSocket.getOutputStream());
pingStream.print("Server listening");
pingStream.flush();
//Now start listening for messages
System.out.println ("Waiting for incoming message - .....");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println ("Server: " + inputLine);
out.println(inputLine);
if (inputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
我曾尝试将Mule的TCP入站端点用作服务器,但我不知道如何识别来自客户端的成功连接,以便触发出站消息。只有当从客户端发送消息时,才会触发流。是否有一种方法可以扩展Mule TCP连接器的功能,并拥有一个可以满足上述要求的侦听器
根据提供的答案,我就是这样实施的-
public class TCPMuleOut extends TcpMessageReceiver {
boolean InitConnection = false;
Socket clientSocket = null;
public TCPMuleOut(Connector connector, FlowConstruct flowConstruct,
InboundEndpoint endpoint) throws CreateException {
super(connector, flowConstruct, endpoint);
}
protected Work createWork(Socket socket) throws IOException {
return new MyTcpWorker(socket, this);
}
protected class MyTcpWorker extends TcpMessageReceiver.TcpWorker {
public MyTcpWorker(Socket socket, AbstractMessageReceiver receiver)
throws IOException {
super(socket, receiver);
// TODO Auto-generated constructor stub
}
@Override
protected Object getNextMessage(Object resource) throws Exception {
if (InitConnection == false) {
clientSocket = this.socket;
logger.debug("Sending logon message");
PrintStream pingStream = new PrintStream(
clientSocket.getOutputStream());
pingStream.print("Log on message");
pingStream.flush();
InitConnection = true;
}
long keepAliveTimeout = ((TcpConnector) connector)
.getKeepAliveTimeout();
Object readMsg = null;
try {
// Create a monitor if expiry was set
if (keepAliveTimeout > 0) {
((TcpConnector) connector).getKeepAliveMonitor()
.addExpirable(keepAliveTimeout,
TimeUnit.MILLISECONDS, this);
}
readMsg = protocol.read(dataIn);
// There was some action so we can clear the monitor
((TcpConnector) connector).getKeepAliveMonitor()
.removeExpirable(this);
if (dataIn.isStreaming()) {
}
return readMsg;
} catch (SocketTimeoutException e) {
((TcpConnector) connector).getKeepAliveMonitor()
.removeExpirable(this);
System.out.println("Socket timeout");
} finally {
if (readMsg == null) {
// Protocols can return a null object, which means we're
// done
// reading messages for now and can mark the stream for
// closing later.
// Also, exceptions can be thrown, in which case we're done
// reading.
dataIn.close();
InitConnection = false;
logger.debug("Client closed");
}
}
return null;
}
}
}
TCP连接器如下所示:
<tcp:connector name="TCP" doc:name="TCP connector"
clientSoTimeout="100000" receiveBacklog="0" receiveBufferSize="0"
sendBufferSize="0" serverSoTimeout="100000" socketSoLinger="0"
validateConnections="true" keepAlive="true">
<receiver-threading-profile
maxThreadsActive="5" maxThreadsIdle="5" />
<reconnect-forever />
<service-overrides messageReceiver="TCPMuleOut" />
<tcp:direct-protocol payloadOnly="true" />
</tcp:connector>
你想做的事情有点难完成,但并非不可能。消息由
org.mule.transport.tcp.TcpMessageReceiver
类接收,该类始终使用输入流中的数据来创建注入流中的消息。
但是,您可以通过在流的TCP连接器(文档化)中添加服务覆盖
标记并替换消息接收器
元素来扩展该接收器并指示TCP模块使用您的接收器。
在扩展接收器中,您应该更改TcpWorker.getNextMessage
方法,以便在从输入流读取之前发送ack消息。
嗯,马科斯。这是个好建议。我想用另一个选项来平衡它:jvas可以使用DevKit创建一个自定义模块,而不是扩展Mule的类(它可以工作,但会使您暴露于内部API更改)。后者会给他演播室的支持作为奖励:)谢谢你MarcosNC和David Dossot。通过扩展TCpMessageReceiver类,我能够做到这一点。我将更新我的解决方案作为答案。