Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mule中的TCP服务器配置-写入客户端套接字_Mule - Fatal编程技术网

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

Mule中的TCP服务器配置-写入客户端套接字,mule,Mule,我正在尝试使用TCP入站端点创建mule流,该端点是侦听端口的TCP服务器。当识别成功的客户端连接时,在接收到来自客户端的任何请求之前,我需要将消息写入套接字(这会让客户端知道我正在侦听),之后客户端才会向我发送进一步的请求。下面是我如何使用示例java程序来实现这一点: import java.net.*; import java.io.*; public class TCPServer { public static void main(String[] args) throws

我正在尝试使用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>

你想做的事情有点难完成,但并非不可能。消息由
org.mule.transport.tcp.TcpMessageReceiver
类接收,该类始终使用输入流中的数据来创建注入流中的消息。 但是,您可以通过在流的TCP连接器(文档化)中添加
服务覆盖
标记并替换
消息接收器
元素来扩展该接收器并指示TCP模块使用您的接收器。 在扩展接收器中,您应该更改
TcpWorker.getNextMessage
方法,以便在从输入流读取之前发送ack消息。
嗯,马科斯。

这是个好建议。我想用另一个选项来平衡它:jvas可以使用DevKit创建一个自定义模块,而不是扩展Mule的类(它可以工作,但会使您暴露于内部API更改)。后者会给他演播室的支持作为奖励:)谢谢你MarcosNC和David Dossot。通过扩展TCpMessageReceiver类,我能够做到这一点。我将更新我的解决方案作为答案。