Mule ESB 3.4.0CE将消息发送到动态添加/删除的多个出站端点

时间:2014-04-09 20:50:18

标签: sockets mule esb

我正在处理Mule ESB应用程序的一部分,我遇到的问题与聊天室非常类似。

聊天室(服务器,Mule ESB)可以监听许多聊天(客户端,外部应用程序),当单个聊天者(c1)输入消息时,服务器会将其回显给除c1之外的所有其他聊天者。在我的情况下,我还需要将它回显给c1。

我很难围绕Mule ESB中消息处理的一些详细方面。我阅读documentation about transports并认为我可能需要使用消息接收者和消息调度程序。

考虑以下配置:

<mule ...>
       <tcp:connector name="tcpConn" doc:name="TCP connector" clientSoTimeout="0" keepAlive="true" keepSendSocketOpen="true" receiveBacklog="0" receiveBufferSize="0" reuseAddress="true" sendBufferSize="0" serverSoTimeout="0" socketSoLinger="0" validateConnections="true">
            <reconnect-forever />
            <tcp:direct-protocol payloadOnly="true"/>
        </tcp:connector>
        </spring:beans>
        <tcp:endpoint exchange-pattern="request-response" host="localhost" port="8090" name="ListenEndpoint" responseTimeout="10000" doc:name="TCP"/>
        <flow name="ChatroomExampleFlow1" doc:name="ChatroomExampleFlow1">
            <tcp:inbound-endpoint exchange-pattern="request-response" ref="ListenEndpoint" responseTimeout="10000" doc:name="Client Message"/>
            <logger level="INFO" doc:name="Logger"/>
            <all doc:name="All">
                <tcp:outbound-endpoint host="${client1.host}" port="${client1.port}" responseTimeout="10000" doc:name="TCP"/>
                <tcp:outbound-endpoint host="${client2.host}" port="${client2.port}" responseTimeout="10000" doc:name="TCP"/>
                <tcp:outbound-endpoint host="${client3.host}" port="${client3.port}" responseTimeout="10000" doc:name="TCP"/>
            </all>

        </flow>
</mule>

如果我在配置时知道所有客户端的主机和端口,则此配置成立。但是,我的目标是能够将消息发送给已建立连接的客户端,这可能最多为n个客户端。随着更多客户端连接/断开连接,我需要在列表中添加或删除它们。

存在<recipient-list expression="#[app.registry.remoteEndpoints]"/>,其中表达式应该评估为端点列表,并且流将消息发送到集合中的每个端点。但是,就我的目的而言,这不起作用(见下面的答案)。 See the documentation for recipient list

<mule ...>
    <tcp:connector name="tcpConn" doc:name="TCP connector" clientSoTimeout="0" keepAlive="true" keepSendSocketOpen="true" receiveBacklog="0" receiveBufferSize="0" reuseAddress="true" sendBufferSize="0" serverSoTimeout="0" socketSoLinger="0" validateConnections="true">
        <reconnect-forever />
        <tcp:direct-protocol payloadOnly="true"/>
    </tcp:connector>
    <spring:beans>
        <spring:bean name="remoteEndpoints" scope="singleton" class="java.util.ArrayList"/>
    </spring:beans>
    <tcp:endpoint  host="localhost" exchange-pattern="one-way" port="8090" name="ListenEndpoint" responseTimeout="10000" doc:name="TCP"/>
    <flow name="ChatroomExampleFlow1" doc:name="ChatroomExampleFlow1">
        <tcp:inbound-endpoint  ref="ListenEndpoint" responseTimeout="10000" doc:name="Client Message"/>
        <echo-component doc:name="Echo"/>
        <component class="EndpointStorer" doc:name="Java"/>
        <recipient-list expression="#[app.registry.remoteEndpoints]"/>
    </flow>
</mule>

并且EndpointStorer看起来像这样:

public Object onCall(MuleEventContext eventContext) throws Exception
    {
        Registry registry = eventContext.getMuleContext().getRegistry();


        MuleMessage message = eventContext.getMessage();
        ArrayList arrList = (ArrayList) registry.get("remoteEndpoints"); 
        Object remoteAddress = message.getOutboundProperty("MULE_REMOTE_CLIENT_ADDRESS");

        String tcpAddr = "tcp://" + remoteAddress.toString().substring(1); //substring 1 because we see the remote client address as something like /127.0.0.1:4943
        if (!arrList.contains(tcpAddr))
        {
            arrList.add(tcpAddr);
        }

        return message;
    }

1 个答案:

答案 0 :(得分:0)

您无法访问已建立的入站TCP连接,至少不使用TCP出站端点。有可能扩展TCP连接器以在http://github.com/mulesoft/mule/blob/mule-3.x/transports/tcp/src/main/中公开插座......但它不是一件小事。

您可以考虑使用AJAX传输。