Mule中的TCP服务器配置 - 写入客户端套接字

时间:2015-03-12 18:40:41

标签: mule

我正在尝试使用TCP入站端点创建一个mule流,这是一个侦听端口的TCP服务器。当识别出成功的客户端连接时,在接收来自客户端的任何请求之前,我需要在套接字中写入一条消息(让客户端知道我正在监听),之后客户端再向我发送请求。这就是我用java程序示例的方法:

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>

1 个答案:

答案 0 :(得分:1)

你要做的事情有点难以完成,但并非不可能。消息由org.mule.transport.tcp.TcpMessageReceiver类接收,并且此类始终使用输入流中的数据来创建注入流中的消息。 但是,您可以通过在flow的tcp连接器中添加service-overrides标记(记录为here)并替换messageReceiver元素来扩展该接收器并指示TCP模块使用您的模块。 。 在扩展接收器中,您应该更改TcpWorker.getNextMessage方法,以便在从输入流中读取之前发送确认消息。 HTH,马科斯。