Java - Play2是WebSockets实现所需的Actors吗?

时间:2015-10-05 16:41:14

标签: java playframework websocket playframework-2.0

我正在尝试使用Play2和Java实现基于WebSockets的解决方案。目前我没有使用Actor Model进行并发管理。相反,它只是handling the WebSockets using callbacks

问题是服务器无法播放'消息传递给多个客户端。例如,我需要所有活动的浏览器会话在通过客户端触发操作后接收简单通知。相反,我只能在单个客户端会话中模拟这个。实际上,它只是作为常规的Ajax请求/响应方案。

我的猜测是Play2& amp;的WebSockets解决方案。具有简单回调的Java无法将消息广播到所有连接的客户端浏览器。

回调服务器代码

public static WebSocket<String> heartUpdate() {
        return new WebSocket<String>() {
            public void onReady(final WebSocket.In<String> in,
                    WebSocket.Out<String> out) {
                in.onMessage(new Callback<String>() {
                    @Override
                    public void invoke(String event) throws Throwable {
                        Product product = Product.find.byId(Long.decode(event));
                        // Other business stuff
                        out.write(entity.id + " " + decimalValue);
                    }
                });
                in.onClose(new Callback0() {
                    @Override
                    public void invoke() throws Throwable {

                    }
                });
                out.write(DELIM_USERID_REP);
            }
        };
    }

路线条目

GET /repsocket   controllers.Application.heartUpdate

客户端

<script>
    // Onto the WebSockets now
    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket;
    var socket = new WS("@routes.Application.heartUpdate.webSocketURL(request)");

    var receiveEvent = function(event) {
        alert(event.data);
        // Notification badge visible with a common text
        $('#notify').text(event.data);
        $('#notify').addClass('visible');
    }
        $('#heart').click(function(e) {
            e.preventDefault();
            socket.send(@product.id);
        });
    socket.onmessage = receiveEvent;
    </script>

在上面的例子中,动作触发客户端是从服务器成功接收消息的动作,而任何其他浏览器会话都没有。

我没有找到任何与Play2 with Java&amp; amp; WebSockets建议强制使用Actors来维持与所有连接的活动客户端的一致通信。

问题: Play2 with Java中的WebSockets是否应该使用Actor Model实现,以便将消息广播到所有活动的客户端会话?

修改 下面的屏幕截图反映了我使用2个有效用户凭据登录到的浏览器的2种状态。

理想情况下,WebSockets&#39;来自服务器的响应应该在两个浏览器上创建相同的通知标记。

enter image description here

1 个答案:

答案 0 :(得分:5)

查看您发布的代码,似乎问题是您没有保存对每个连接的引用,因此您可以稍后广播消息。像这样:

// Just an example: does not deal with concurrency problems
private static final Set<WebSocket.Out<String>> SOCKETS = new HashSet<>();

public static WebSocket<String> heartUpdate() {
    return new WebSocket<String>() {
        public void onReady(final WebSocket.In<String> in,
                    final WebSocket.Out<String> out) {
            SOCKETS.add(out);
            in.onMessage(new Callback<String>() {
                @Override
                public void invoke(String event) throws Throwable {
                    for(WebSocket.Out<String> s: SOCKETS) {
                        s.write("SOME MESSAGE");    
                    }
                }
            });
            in.onClose(new Callback0() {
                @Override
                public void invoke() throws Throwable {
                    SOCKETS.remove(out);
                }
            });
        }
    };
}

你也可以使用actor来模拟这个问题:让一个actor负责跟踪连接并处理新的套接字连接/关闭。

如果您想使用Akka,可以some activator templates开始使用。